1

I have a code in which for 3 different values of D ,i have 3 different values of dx and so,3 different plots.

I want to do a plot which will have all 3 plots in one.

...
D=(0.133e-4,0.243e-4,0.283e-4)

dx=sc.zeros(3)
    for i in D:
        dx[i]=sc.sqrt(D[i]*dt/M)

        plt.ion()
        while n<N:
            Vw_n=Vw_n1
            C_n=C_n1
            R2=(Vw_n+B1)/(Vw_0+B1)
            Cc=C_n1[0]/C0
            F2_1=10000/3*Pw*A*(C0*Vw_0/Vw_n1-C_n[1])
            dV=F2_1*dt
            Vw_n1=Vw_n+dV
            C_n1[0]=C0*Vw_0/Vw_n1
            F_i_2=-D[i]/dx[i]*(C_n[1:7]-C_n[0:6])
            C_n1[0:6]=C_n[0:6]-F_i_2*A*dt/(L/(V0/A)*V0/5)
            n+=1
            ttime=n*0.02*1000

            #-----PLOT AREA---------------------------------#

            mylabels=('T=273','T=293','T=298')
            colors=('-b','or','+k')

            if x==1:
                plt.plot(ttime,R2,mylabels[i],colors[i])
            elif x==2:
                plt.plot(ttime,Cc,mylabels[i],colors[i])
            plt.draw()
            plt.show()

----------RUNNABLE--------------------------

import scipy as sc
import matplotlib.pyplot as plt


def graph(x):

    A=1.67e-6  
    V0=88e-12 
    Vw_n1=71.7/100*V0 
    Pw=0.22   
    L=4e-4
    B1=V0-Vw_n1   

    C7=0.447e-3  



    dt=0.2e-4
    M=0.759e-1

    C_n1=sc.zeros(7)
    C_n1[0:6]=0.290e-3
    C_n1[6]=0.447e-3


    C0=C_n1[0]
    Vw_0=Vw_n1

    N=2000 
    n =1
    D = ,0.243e-4
    dx = sc.sqrt(D*dt/M)

        plt.ion()
        while n<N:
            Vw_n=Vw_n1
            C_n=C_n1
            R2=(Vw_n+B1)/(Vw_0+B1)
            Cc=C_n1[0]/C0
            F2_1=10000/3*Pw*A*(C0*Vw_0/Vw_n1-C_n[1])
            dV=F2_1*dt
            Vw_n1=Vw_n+dV
            C_n1[0]=C0*Vw_0/Vw_n1
            F_i_2=-D/dx*(C_n[1:7]-C_n[0:6])
            C_n1[0:6]=C_n[0:6]-F_i_2*A*dt/(L/(V0/A)*V0/5)
            n+=1
            ttime=n*0.02*1000

            #-----PLOT AREA---------------------------------#


            if x==1:
                plt.plot(ttime,R2)
            elif x==2:
                plt.plot(ttime,Cc)
            plt.draw()
            plt.show()

My problem is that i want to plot (ttime,R2) and (ttime,Cc). But i can't figure how to call R2 and Cc for the 3 different values of D (and dx).

Also, i am taking an error: tuple indices must be integers, not float

at dx[i]=sc.sqrt(D[i]*dt/M).

Thanks!

George
  • 5,808
  • 15
  • 83
  • 160

1 Answers1

2

Consider these lines:

D=(0.133e-4,0.243e-4,0.283e-4)
for i in D:
    dx[i]=sc.sqrt(D[i]*dt/M)

i is a float. It can not be used as an index into the tuple D. (D[i] does not make sense.)

Perhaps you meant

D=(0.133e-4,0.243e-4,0.283e-4)
for i, dval in enumerate(D):
    dx[i] = sc.sqrt(dval*dt/M)

Or, simply

import scipy as sc
D = sc.array([0.133e-4,0.243e-4,0.283e-4])
dx = sc.sqrt(D*dt/M)

  • Don't call plt.plot once for each point. That road leads to sluggish behavior. Instead, accumulate an entire curve's worth of data points, and then call plt.plot once for the entire curve.
  • To plot 3 curves on the same figure, simply call plt.plot 3 times. Do that first before calling plt.show().
  • The while not flag loop was not ending when you enter 1 for x, because if x==2 should have been elif x==2.
  • To animate a matplotlib plot, you should still try to avoid multiple calls to plt.plot. Instead, use plt.plot once to make a Line2D object, and then update the underlying data with calls to line.set_xdata and line.set_ydata. See Joe Kington's example and this example from the matplotlib docs.

import scipy as sc
import matplotlib.pyplot as plt

def graph(x):
    plt.ion()
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    lines = []
    D = (0.133e-4, 0.243e-4, 0.283e-4)
    temperatures = ('T = 273','T = 293','T = 298')
    N = 2000
    linestyles = ('ob', '-r', '+m')
    for dval, linestyle, temp in zip(D, linestyles, temperatures):
        line, = ax.plot([], [], linestyle, label = temp) 
        lines.append(line)
    plt.xlim((0, N*0.02*1000))        
    if x == 1:
        plt.ylim((0.7, 1.0))
    else:
        plt.ylim((1.0, 1.6))
    plt.legend(loc = 'best')        
    for dval, line in zip(D, lines):
        A = 1.67e-6
        V0 = 88e-12
        Vw_n1 = 71.7/100*V0
        Pw = 0.22
        L = 4e-4
        B1 = V0-Vw_n1
        C7 = 0.447e-3
        dt = 0.2e-4
        M = 0.759e-1
        C_n1 = sc.zeros(7)
        C_n1[0:6] = 0.290e-3
        C_n1[6] = 0.447e-3
        C0 = C_n1[0]
        Vw_0 = Vw_n1

        tvals = []
        yvals = []
        dx = sc.sqrt(dval*dt/M)
        for n in range(1, N+1, 1):
            Vw_n = Vw_n1
            C_n = C_n1
            R2 = (Vw_n+B1)/(Vw_0+B1)
            Cc = C_n1[0]/C0
            F2_1 = 10000/3*Pw*A*(C0*Vw_0/Vw_n1-C_n[1])
            dV = F2_1*dt
            Vw_n1 = Vw_n+dV
            C_n1[0] = C0*Vw_0/Vw_n1
            F_i_2 = -dval/dx*(C_n[1:7]-C_n[0:6])
            C_n1[0:6] = C_n[0:6]-F_i_2*A*dt/(L/(V0/A)*V0/5)
            tvals.append(n*0.02*1000)
            yvals.append(R2 if x == 1 else Cc)
            if not len(yvals) % 50:
                line.set_xdata(tvals)
                line.set_ydata(yvals)
                fig.canvas.draw()

if __name__ == "__main__":
    flag = False
    while not flag:
        try:
            x = int(raw_input("Give a choice 1  or 2  : "))
            flag = True
            if x == 1:
                plt.title('Change in cell volume ratio as a function of time \n\
                at various temperatures')
                plt.xlabel('Time')
                plt.ylabel('Ceil volume ratio (V/V0)')
                graph(x)
            elif x == 2:
                plt.title('Increase of solute concentration at various temperatures')
                plt.xlabel('Time')
                plt.ylabel('Solute concentration in the Ceil (Cc)')
                graph(x)
            else:
                flag = False
                print("You must input 1 or 2")
        except ValueError:
            print("You must input 1 or 2")
    raw_input('Press a key when done')
Community
  • 1
  • 1
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • :(i updated) I use scipy arrays.Now (weird why?) when i input "1",the program just shows the message "You must input 1 or 2" and doesn't run.Also,you didn't answer to my other question about how to to this "plt.plot(ttime,R2,mylabels[i],colors[i]) " to work for the 3 different values.I don't know how to manipulate R2.Thank you! – George Jan 31 '12 at 17:26
  • 1
    Can you provide a short, **simplified**, runnable example? I have no idea what any of those many variables mean nor what is going wrong. – unutbu Jan 31 '12 at 18:20
  • :Ok,i gave you a runnable code.It works for one value of D.I want to do it able to run for the 3 values.(also,plot in one plot all 3 different plots fro the 3 values).If you see my previous code ,you will understand what i am trying to do.Thanks! – George Jan 31 '12 at 20:38
  • :First of all ,thanks a lot!!Almost perfect!One thing.Calling plot as "plt.plot(tvals,yvals,'-')" results in mixing the plots.I tried sth like :colors=('ob','-r','+m'),but i don't know how to put it in the above call of plot.Is there a way? – George Jan 31 '12 at 21:12
  • To conform with matplotlib terminology, I'm renaming `colors` --> `linestyles`. You can loop through the values of `D` and `linestyles` with `for dval, linestyle in zip(D,linestyles)`. The code above has been edited to show what I mean. – unutbu Jan 31 '12 at 21:19
  • :Hmm,sth goes wrong.It supposes to give almost the same plot for all 3 values of D.Instead,it gives 1 plot (the right plot) and another which is line. – George Jan 31 '12 at 21:25
  • I've moved the "constants" back inside the `for dval ...` loop. I think perhaps some of those were not constants, but instead needed to be re-initialized for each value of `D`. – unutbu Jan 31 '12 at 21:36
  • :just wondering.The plt.ion() and plt.draw() don't seem to work now .They work only for one plot?(Because now we draw 3 plots in 1) – George Jan 31 '12 at 22:04
  • What effect are you trying to achieve with `plt.ion` and `plt.draw`? – unutbu Jan 31 '12 at 22:12
  • :Ok,thanks again!Now,one final (i am taking advantage of you :)).I want to put legends,so i do :"temperatures=('T=273','T=293','T=298')" , "for dval, linestyle ,temp in zip(D, linestyles,temperatures): " and then "plt.plot(tvals,yvals,linestyle)" and "plt.legend(temp)" but it doesn't show the values of T.Just the legend with colors.(If you don't answer,i totally understand).Thanks a lot! – George Feb 01 '12 at 10:47
  • To show the string in the legend, add `label = temp` to the `ax.plot` line. I don't know why the legend shows the marker icon twice (e.g. `+ +`), but that seems to be the [default behavior](http://matplotlib.sourceforge.net/users/legend_guide.html). – unutbu Feb 01 '12 at 11:00