0

I'm trying to draw a piece-wise function in matplotlib. My filtering approach (which is based on Ami's answer here) does not work:

ValueError: x and y must have same first dimension

Could you fix the issue, please?

import numpy as np
import matplotlib.pyplot as plt

gK_inf = 7.06
gK_0 = 0.09
tauN = 0.75

gK_inf1 = 0.09
gK_01 = 7.06
tauN1 = 1.1

def graph(formula, formula1, t_range):  
    t = np.fromiter(t_range, np.float)
    gK = formula(t)
    gK1 = formula1(t)
    plt.plot(t,gK)
    plt.plot(t,gK1)
    plt.xlabel(r"$t(msec.)$")
    plt.ylabel(r"$g_K$")
    plt.show()  

def my_formula(t):
    if np.all(t>0) and np.all(t<5):
        return np.power((np.power(gK_inf,0.25))-((np.power(gK_inf,0.25)-np.power(gK_0,0.25))*np.exp(-t/tauN)),4)
    else:
        return 0

def my_formula1(t):
    if np.all(t>5) and np.all(t<10):
        return np.power((np.power(gK_inf1,0.25))-((np.power(gK_inf1,0.25)-np.power(gK_01,0.25))*np.exp(-t/tauN1)),4)
    else:
        return 0

graph(my_formula, my_formula1, np.arange(0,10,0.1))

Update:

According to @Michael advice, the error is removed, but the result is not what it must be:

enter image description here

Actually, formula and formula1must be plotted in ranges [0,5] and [5,10], respectively.

This is what I need:

enter image description here

3
  • Is the plot in the update an expected output? Then I don't get why you use np.all and the return 0 for the blue curve (doesn't go to zero for t>5). Please specify in more detail what you want (besides fixing the error message). Commented Apr 9, 2017 at 8:24
  • @Michael: You're right. The logic of my code is not what it is supposed to be. I'd added a sketch to illustrate what I need, if you kindly check it. Commented Apr 9, 2017 at 8:29
  • 1
    ok so you want one curve. I think I get it now. I'm gonna try it and then edit my answer. Commented Apr 9, 2017 at 8:30

1 Answer 1

0

You should replace return 0 in both my_formula and my_formula1 with return np.zeros_like(t).

plt.plot expects arrays of same shape. With your input data np.arange(0,5,0.1) you always reach that case return 0 which is an int. If you want you can think of that as an array with shape (1,) (strictly speaking this is not true, if you try 0.shape you get an error). Then you try to plot one y-value with 50 x-values. Even though it might seem logical to you to just always take the same y value, this is not how plt.plot works. When you use np.zeros_like(t) you get an array with 50 zero entries and plt.plot knows what to plot.


EDIT

According to the update, I came up with this:

import numpy as np
import matplotlib.pyplot as plt

gK_inf = 7.06
gK_0 = 0.09
tauN = 0.75

gK_inf1 = 0.09
gK_01 = 7.06
tauN1 = 1.1

def graph(formula, t_range):  
    t = np.fromiter(t_range, np.float)
    gK = formula(t)
    plt.plot(t,gK)
    plt.xlabel(r"$t(msec.)$")
    plt.ylabel(r"$g_K$")
    plt.show()  

def my_formula(t):
    result = np.power((np.power(gK_inf,0.25))-((np.power(gK_inf,0.25)-np.power(gK_0,0.25))*np.exp(-t/tauN)),4) *(t>=0)*(t<5)
    result += np.power((np.power(gK_inf1,0.25))-((np.power(gK_inf1,0.25)-np.power(gK_01,0.25))*np.exp(-(t-5)/tauN1)),4) *(t>=5)*(t<=10)
    return result

graph(my_formula, np.arange(0.0,12,0.1))

The formula applied for a certain t-value is decided with the boolean arrays (t>=0)*(t<5) and (t>=5)*(t<=10). When they are multiplied with the float array, they are cast to 0 for False and 1 for True so it is always the right formula for the t-ranges applied. Also I changed something in the formula for 5<=t<=10: To make it look like your expected output, I had to shift the exponential function: np.exp(-t/tauN1)) was replaced with np.exp(-(t-5)/tauN1)).

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. Could you please have a look at my update? The filtering approach does not work at all.
Thanks in advance for your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.