How to plot graphs from equations - python

I am trying to replicate some graphs from 3 equations.
My equation are shown in my python code below
The first two equations are plotted on the 1st graph
The first equation and the 3rd equation are plotted on the 2nd graph
The last two equations are plotted on the 3rd graph
My parameters are:
k1 = a range of values, k2=1, n1=3, n2=3, K1=0.3, K2=0.3, b1=0, b2=0.05
i'm unsure about how to plot this on a graph. any help would be great. thanks
note that i am a python beginner and have basic knowledge of coding
here's my code so far:
import numpy as np
import matplotlib.pyplot as plt
rateinact= k1*X
rateact12= k2*(b2*(K2**n2/(K2**n2 + X**n2)) + (X**n2/(K2**n2 + X**n2))*(1-X)
Rateinact2 = k1*(B1*((X**n1)/(K1**n1+X**n1))+((K1**n1)/(K1**n1+X**n1)))*(X)
#define parameters
k1 = []
k2=1
n1=3
n2=3
K1=0.3
K2=0.3
b1=0
b2=0.05
#graph 1
plt.plot(inact, 'r')
plt.plot(act12, 'b')
plt.ylabel('Rate of A inactivation or activation')
plt.xlabel('Fraction of activated A)
plt.show()

The trick you seem to be missing is how to make a range of values. This can be easily done with np.linspace since you're already using numpy.
x = np.linspace(0,1,100)
y = x**2 + 3*x + 4
plt.plot(x,y,'g-')
Or, for your specific example, with the syntax errors removed (I had to guess a little on what some values were):
-- EDIT --
I see now a little better what you wanted. Here's a quick demo of how you might accomplish this (I'm using subfigures instead of separate figures, but the idea is the same):
import numpy as np
import matplotlib.pyplot as plt
k1 = np.linspace(0,1,5)
k2=1
n1=3
n2=3
K1=0.3
K2=0.3
beta1=0
beta2=0.05
x = np.linspace(0,1)
def r_inact_1loop(x,k1=1):
return k1*x
def r_activation(x,k1=1):
return k2*(beta2*K2**n2/(K2**n2+x**n2) + x**n2/(K2**n2+x**n2))*(1-x)
def r_inact_2loop(x,k1=1):
return k1*(beta1*x**n1/(K1**n1+x**n1) + K1**n1/(K1**n1+x**n1))*x
#define parameters
#graph 1
fig = plt.figure(figsize=(16,8))
ax1 = fig.add_subplot(1,3,1)
ax2 = fig.add_subplot(1,3,2)
ax3 = fig.add_subplot(1,3,3)
ax1.set_xlabel('Fraction of activated A')
ax2.set_xlabel('Fraction of activated A')
ax3.set_xlabel('Fraction of activated A')
ax1.set_ylabel('Rate of A inactivation or activation')
ax2.set_ylabel('Rate of A inactivation or activation')
ax3.set_ylabel('Rate of A inactivation or activation')
for k in k1:
ax1.plot(x,r_inact_1loop(x,k),label='in1 k1={:.1f}'.format(k))
ax1.plot(x,r_activation(x,k),label='ac k1={:.1f}'.format(k))
ax1.legend(loc='best')
ax2.plot(x,r_inact_1loop(x,k),label='in1 k1={:.1f}'.format(k))
ax2.plot(x,r_inact_2loop(x,k),label='in2 k1={:.1f}'.format(k))
ax1.set_xlabel('Fraction of activated A')
ax2.legend(loc='best')
ax3.plot(x,r_activation(x,k),label='ac k1={:.1f}'.format(k))
ax3.plot(x,r_inact_2loop(x,k),label='in2 k1={:.1f}'.format(k))
ax3.legend(loc='best')
plt.show()
--ADDENDUM--
If you want the cool shading of the plots you were looking at, here's the code for that
ax2.fill_between(x,r_inact_1loop(x,k1[0]),r_inact_1loop(x,k1[-1]))
ax3.fill_between(x,r_inact_2loop(x,k1[0]),r_inact_2loop(x,k1[-1]))

Related

How to split data into two graphs with mat plot lib

I would be so thankful if someone would be able to help me with this. I am creating a graph in matplotib however I would to love to split up the 14 lines created from the while loop into the x and y values of P, so instead of plt.plot(t,P) it would be plt.plot(t,((P[1])[0]))) and
plt.plot(t,((P[1])[1]))). I would love if someone could help me very quick, it should be easy but i am just getting errors with the arrays
`
#Altering Alpha in Tumor Cells vs PACCs
#What is alpha? α = Rate of conversion of cancer cells to PACCs
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from google.colab import files
value = -6
counter = -1
array = []
pac = []
while value <= 0:
def modelP(x,t):
P, C = x
λc = 0.0601
K = 2000
α = 1 * (10**value)
ν = 1 * (10**-6)
λp = 0.1
γ = 2
#returning odes
dPdt = ((λp))*P*(1-(C+(γ*P))/K)+ (α*C)
dCdt = ((λc)*C)*(1-(C+(γ*P))/K)-(α*C) + (ν***P)
return dPdt, dCdt
#initial
C0= 256
P0 = 0
Pinit = [P0,C0]
#time points
t = np.linspace(0,730)
#solve odes
P = odeint(modelP,Pinit,t)
plt.plot(t,P)
value += 1
#plot results
plt.xlabel('Time [days]')
plt.ylabel('Number of PACCs')
plt.show()
`
You can use subplots() to create two subplots and then plot the individual line into the plot you need. To do this, firstly add the subplots at the start (before the while loop) by adding this line...
fig, ax = plt.subplots(2,1) ## Plot will 2 rows, 1 column... change if required
Then... within the while loop, replace the plotting line...
plt.plot(t,P)
with (do take care of the space so that the lines are within while loop)
if value < -3: ## I am using value = -3 as the point of split, change as needed
ax[0].plot(t,P)#, ax=ax[0]) ## Add to first plot
else:
ax[1].plot(t,P)#,ax=ax[1]) ## Add to second plot
This will give a plot like this.

How can I create a 4D complex surface plot? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I have the following Matlab code that I would like to be converted to a Python 3 one.
r = (0:1:15)'; % create a matrix of complex inputs
theta = pi*(-2:0.05:2);
z = r*exp(1i*theta);
%w = z.^(1/2) ; % calculate the complex outputs
w = sqrt(r)*exp(1i*theta/2);
figure('Name','Graphique complexe','units','normalized','outerposition',[ 0.08 0.1 0.8 0.55]);
subplot(121)
surf(real(z),imag(z),real(w),imag(w)) % visualize the complex function using surf
xlabel('Real(z)')
ylabel('Imag(z)')
zlabel('Real(u)')
cb = colorbar;
colormap jet; % gradient from blue to red
cb.Label.String = 'Imag(v)';
subplot(122)
surf(real(z),imag(z),imag(w),real(w)) % visualize the complex function using surf
xlabel('Real(z)')
ylabel('Imag(z)')
zlabel('Imag(v)')
cb = colorbar;
colormap jet; % gradient from blue to red
cb.Label.String = 'Real(u)';
The results and original discussions can be found here. There's also a discussion available on this SO page. However, I failed to run and reproduce those codes. What can I try next?
This is perfectly straightforward if you spend the time learning how matplotlib (and 3d axes in particular) work:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from mpl_toolkits.mplot3d import Axes3D
# compute data to plot
r, theta = np.mgrid[1:16, -2*np.pi:2*np.pi:50j]
z = r * np.exp(1j*theta)
w = np.sqrt(r) * np.exp(1j*theta/2)
# plot data
fig = plt.figure()
for plot_index in [1, 2]:
if plot_index == 1:
z_data, c_data = w.real, w.imag
z_comp, c_comp = 'Re', 'Im'
else:
z_data, c_data = w.imag, w.real
z_comp, c_comp = 'Im', 'Re'
c_data = (c_data - c_data.min()) / c_data.ptp()
colors = cm.viridis(c_data)
ax = fig.add_subplot(f'12{plot_index}', projection='3d')
surf = ax.plot_surface(z.real, z.imag, z_data, facecolors=colors,
clim=[z_data.min(), z_data.max()])
ax.set_xlabel('$Re z$')
ax.set_ylabel('$Im z$')
ax.set_zlabel(f'${z_comp} w$')
cb = plt.colorbar(surf, ax=ax)
cb.set_label(f'${c_comp} w$')
plt.show()
The result:
Some things that should be noted:
Viridis colormap is good, jet is bad.
In general there could be rendering issues with complex (interlocking) 3d geometries, because matplotlib has a 2d renderer. Fortunately, in this case the dataset is tightly coupled enough that this doesn't seem to happen, even if you rotate around the figure interactively. (But if you were to plot two intersecting surfaces together, things would probably be different.)
One might want to enable latex rendering of labels to make the result extra crispy.
The shading looks a lot better if you use the default option of colouring according to the z component of the data.
If we also want to port the second part of my MATLAB answer you will have to use a trick to stitch together the two branches of the function (which, as I said, is necessary to render interlocking surfaces properly). For the specific example in the above code this will not give you perfect results, since both branches themselves contain discontinuities in the imaginary part, so regardless of our efforts in rendering the two surfaces nicely, the result will look a bit bad:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from mpl_toolkits.mplot3d import Axes3D
# compute data to plot
r0 = 15
re, im = np.mgrid[-r0:r0:31j, -r0:r0:31j]
z = re + 1j*im
r, theta = abs(z), np.angle(z)
w1 = np.sqrt(r) * np.exp(1j*theta/2) # first branch
w2 = np.sqrt(r) * np.exp(1j*(theta + 2*np.pi)/2) # second branch
# plot data
fig = plt.figure()
for plot_index in [1, 2]:
# construct transparent bridge
re_bridge = np.vstack([re[-1, :], re[0, :]])
im_bridge = np.vstack([im[-1, :], im[0, :]])
c_bridge = np.full(re_bridge.shape + (4,), [1, 1, 1, 0]) # 0% opacity
re_surf = np.vstack([re, re_bridge, re])
im_surf = np.vstack([im, im_bridge, im])
w12 = np.array([w1, w2])
if plot_index == 1:
z_comp, c_comp = 'Re', 'Im'
z12, c12 = w12.real, w12.imag
else:
z_comp, c_comp = 'Im', 'Re'
z12, c12 = w12.imag, w12.real
color_arrays = cm.viridis((c12 - c12.min()) / c12.ptp())
z1,z2 = z12
c1,c2 = color_arrays
z_bridge = np.vstack([z1[-1, :], z2[0, :]])
z_surf = np.vstack([z1, z_bridge, z2])
c_surf = np.vstack([c1, c_bridge, c2])
ax = fig.add_subplot(f'12{plot_index}', projection='3d')
surf = ax.plot_surface(re_surf, im_surf, z_surf, facecolors=c_surf,
clim=[c12.min(), c12.max()],
rstride=1, cstride=1)
ax.set_xlabel('$Re z$')
ax.set_ylabel('$Im z$')
ax.set_zlabel(f'${z_comp} w$')
cb = plt.colorbar(surf, ax=ax)
cb.set_label(f'${c_comp} w$')
plt.show()
The ugly jump in the right figure might be fixed with a lot of work, but it won't be easy: it's an actual discontinuity in both surface datasets occuring at negative real arguments. Since your actual problem is probably more like this, you will probably not need to face this issue, and you can use the above stitching (bridging) trick to combine your surfaces.

Python plotting to different figures fails

EDIT: I figured out that the Problem always occours if one tries to plot to two different lists of figures. Does that mean that one can not do plots to different figure-lists in the same loop? See latest code for much simpler sample of a problem.
I try to analyze a complex set of data which consists basically about measurements of electric devices under different conditions. Hence, the code is a bit more complex but I tried to strip it down to a working example - however it is still pretty long. Hence, let me explain what you see: You see 3 classes with Transistor representing an electronic device. It's attribute Y represents the measurement data - consisting of 2 sets of measurements. Each Transistor belongs to a group - 2 in this example. And some groups belong to the same series - one series where both groups are included in this example.
The aim is now to plot all measurement data for each Transistor (not shown), then to also plot all data belonging to the same group in one plot each and all data of the same series to one plot. In order to program it in an efficent way without having a lot of loops my idea was to use the object orientated nature of matplotlib - I will have figures and subplots for each level of plotting (initialized in initGrpPlt and initSeriesPlt) which are then filled with only one loop over all Transistors (in MainPlt: toGPlt and toSPlt). In the end it should only be printed / saved to a file / whatever (PltGrp and PltSeries).
The Problem: Even though I specify where to plot, python plots the series plots into the group plots. You can check this yourself by running the code with the line 'toSPlt(trans,j)' and without. I have no clue why python does this because in the function toSPlt I explicetly say that python should use the subplots from the series-subplot-list. Would anyone have an idea to why this is like this and how to solve this problem in an elegent way?
Read the code from the bottom to the top, that should help with understanding.
Kind regards
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
maxNrVdrain = 2
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
A = [[1*np.cos(X),2*np.cos(X),3*np.cos(X),4*np.cos(X)],[1*np.tan(X),2*np.tan(X),3*np.tan(X),4*np.tan(X)]]
B = [[2* np.sin(X),4* np.sin(X),6* np.sin(X),8* np.sin(X)],[2*np.cos(X),4*np.cos(X),6*np.cos(X),8*np.cos(X)]]
class Transistor(object):
_TransRegistry = []
def __init__(self,y1,y2):
self._TransRegistry.append(self)
self.X = X
self.Y = [y1,y2]
self.group = ''
class Groups():
_GroupRegistry = []
def __init__(self,trans):
self._GroupRegistry.append(self)
self.transistors = [trans]
self.figlist = []
self.axlist = []
class Series():
_SeriesRegistry = []
def __init__(self,group):
self._SeriesRegistry.append(self)
self.groups = [group]
self.figlist = []
self.axlist = []
def initGrpPlt():
for group in Groups._GroupRegistry:
for j in range(maxNrVdrain):
group.figlist.append(plt.figure(j))
group.axlist.append(group.figlist[j].add_subplot(111))
return
def initSeriesPlt():
for series in Series._SeriesRegistry:
for j in range(maxNrVdrain):
series.figlist.append(plt.figure(j))
series.axlist.append(series.figlist[j].add_subplot(111))
return
def toGPlt(trans,j):
colour = cm.rainbow(np.linspace(0, 1, 4))
group = trans.group
group.axlist[j].plot(trans.X,trans.Y[j], color=colour[group.transistors.index(trans)], linewidth=1.5, linestyle="-")
return
def toSPlt(trans,j):
colour = cm.rainbow(np.linspace(0, 1, 2))
series = Series._SeriesRegistry[0]
group = trans.group
if group.transistors.index(trans) == 0:
series.axlist[j].plot(trans.X,trans.Y[j],color=colour[series.groups.index(group)], linewidth=1.5, linestyle="-", label = 'T = nan, RH = nan' )
else:
series.axlist[j].plot(trans.X,trans.Y[j],color=colour[series.groups.index(group)], linewidth=1.5, linestyle="-")
return
def PltGrp(group,j):
ax = group.axlist[j]
ax.set_title('Test Grp')
return
def PltSeries(series,j):
ax = series.axlist[j]
ax.legend(loc='upper right', frameon=False)
ax.set_title('Test Series')
return
def MainPlt():
initGrpPlt()
initSeriesPlt()
for trans in Transistor._TransRegistry:
for j in range(maxNrVdrain):
toGPlt(trans,j)
toSPlt(trans,j)#plots to group plot for some reason
for j in range(maxNrVdrain):
for group in Groups._GroupRegistry:
PltGrp(group,j)
plt.show()
return
def Init():
for j in range(4):
trans = Transistor(A[0][j],A[1][j])
if j == 0:
Groups(trans)
else:
Groups._GroupRegistry[0].transistors.append(trans)
trans.group = Groups._GroupRegistry[0]
Series(Groups._GroupRegistry[0])
for j in range(4):
trans = Transistor(B[0][j],B[1][j])
if j == 0:
Groups(trans)
else:
Groups._GroupRegistry[1].transistors.append(trans)
trans.group = Groups._GroupRegistry[1]
Series._SeriesRegistry[0].groups.append(Groups._GroupRegistry[1])
return
def main():
Init()
MainPlt()
return
main()
latest example that does not work:
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
Y1 = np.cos(X)
Y2 = np.sin(X)
figlist1 = []
figlist2 = []
axlist1 = []
axlist2 = []
for j in range(4):
figlist1.append(plt.figure(j))
axlist1.append(figlist1[j].add_subplot(111))
figlist2.append(plt.figure(j))#this should be a new set of figures!
axlist2.append(figlist2[j].add_subplot(111))
colour = cm.rainbow(np.linspace(0, 1, 4))
axlist1[j].plot(X,j*Y1, color=colour[j], linewidth=1.5, linestyle="-")
axlist1[j].set_title('Test Grp 1')
colour = cm.rainbow(np.linspace(0, 1, 4))
axlist2[j].plot(X,j*Y2, color=colour[int(j/2)], linewidth=1.5, linestyle="-")
axlist2[j].set_title('Test Grp 2')
plt.show()
Ok, stupid mistake if one thinks of the Background but maybe someone has a similar Problem and is unable to see the cause as I was first. So here is the solution:
The Problem is that the Name of the listobjects like figlist1[j] do not define the figure - they are just pointers to the actual figure object. and if such an object is created by plt.figure(j) one has to make sure that j is different for each figure - hence, in a Loop where multiple figures shall be initialized one Needs to somehow Change the number of the figure or the first object will be overwritten. Hope that helps! Cheers.

Solving nonlinear differential first order equations using Python

I would like to solve a nonlinear first order differential equation using Python.
For instance,
df/dt = f**4
I wrote the following program, but I have an issue with matplotlib, so I don't know if the method I used with scipy is correct.
from scipy.integrate import odeint
import numpy as np
import matplotlib.pyplot as plt
derivate=lambda f,t: f**4
f0=10
t=np.linspace(0,2,100)
f_numeric=scipy.integrate.odeint(derivate,f0,t)
print(f_numeric)
plt.plot(t,f_numeric)
plt.show()
Which results in the following error:
AttributeError: 'float' object has no attribute 'rint'
In this case, you might be better of using Sympy, which allows you to obtain the closed form solutions:
from IPython.display import display
import sympy as sy
from sympy.solvers.ode import dsolve
import matplotlib.pyplot as plt
import numpy as np
sy.init_printing() # LaTeX like pretty printing for IPython
t = sy.symbols("t", real=True)
f = sy.symbols("f", function=True)
eq1 = sy.Eq(f(t).diff(t), f(t)**4) # the equation
sls = dsolve(eq1) # solvde ODE
# print solutions:
print("For ode")
display(eq1)
print("the solutions are:")
for s in sls:
display(s)
# plot solutions:
x = np.linspace(0, 2, 100)
fg, axx = plt.subplots(2, 1)
axx[0].set_title("Real part of solution of $\\frac{d}{dt}f(t)= (f(t))^4$")
axx[1].set_title("Imag. part of solution of $\\frac{d}{dt}f(t)= (f(t))^4$")
fg.suptitle("$C_1=0.1$")
for i, s in enumerate(sls, start=1):
fn1 = s.rhs.subs("C1", .1) # C_1 -> 1
fn2 = sy.lambdify(t, fn1, modules="numpy") # make numpy function
y = fn2(x+0j) # needs to be called with complex number
axx[0].plot(x, np.real(y), label="Sol. %d" % i)
axx[1].plot(x, np.imag(y), label="Sol. %d" % i)
for ax in axx:
ax.legend(loc="best")
ax.grid(True)
axx[0].set_ylabel("Re$\\{f(t)\\}$")
axx[1].set_ylabel("Im$\\{f(t)\\}$")
axx[-1].set_xlabel("$t$")
fg.canvas.draw()
plt.show()
In an IPython shell, you should see the following:

Solving a linear-quadratic system of equations, both graphically and numerically, in numpy/matplotlib?

I have a system of a linear equation and a quadratic equation that I can set up with numpy and scipy so I can get a graphical solution. Consider the example code:
#!/usr/bin/env python
# Python 2.7.1+
import numpy as np #
import matplotlib.pyplot as plt #
# d is a constant;
d=3
# h is variable; depends on x, which is also variable
# linear function:
# condition for h: d-2x=8h; returns h
def hcond(x):
return (d-2*x)/8.0
# quadratic function:
# condition for h: h^2+x^2=d*x ; returns h
def hquad(x):
return np.sqrt(d*x-x**2)
# x indices data
xi = np.arange(0,3,0.01)
# function values in respect to x indices data
hc = hcond(xi)
hq = hquad(xi)
fig = plt.figure()
sp = fig.add_subplot(111)
myplot = sp.plot(xi,hc)
myplot2 = sp.plot(xi,hq)
plt.show()
That code results with this plot:
It's clear that the two functions intersect, thus there is a solution.
How could I automatically solve what is the solution (the intersection point), while keeping most of the function definitions intact?
It turns out one can use scipy.optimize.fsolve to solve this, just need to be careful that the functions in the OP are defined in the y=f(x) format; while fsolve will need them in the f(x)-y=0 format. Here is the fixed code:
#!/usr/bin/env python
# Python 2.7.1+
import numpy as np #
import matplotlib.pyplot as plt #
import scipy
import scipy.optimize
# d is a constant;
d=3
# h is variable; depends on x, which is also variable
# linear function:
# condition for h: d-2x=8h; returns h
def hcond(x):
return (d-2*x)/8.0
# quadratic function:
# condition for h: h^2+x^2=d*x ; returns h
def hquad(x):
return np.sqrt(d*x-x**2)
# for optimize.fsolve;
# note, here the functions must be equal to 0;
# we defined h=(d-2x)/8 and h=sqrt(d*x-x^2);
# now we just rewrite in form (d-2x)/16-h=0 and sqrt(d*x-x^2)-h=0;
# thus, below x[0] is (guess for) x, and x[1] is (guess for) h!
def twofuncs(x):
y = [ hcond(x[0])-x[1], hquad(x[0])-x[1] ]
return y
# x indices data
xi = np.arange(0,3,0.01)
# function values in respect to x indices data
hc = hcond(xi)
hq = hquad(xi)
fig = plt.figure()
sp = fig.add_subplot(111)
myplot = sp.plot(xi,hc)
myplot2 = sp.plot(xi,hq)
# start from x=0 as guess for both functions
xsolv = scipy.optimize.fsolve(twofuncs, [0, 0])
print(xsolv)
print("xsolv: {0}\n".format(xsolv))
# plot solution with red marker 'o'
myplot3 = sp.plot(xsolv[0],xsolv[1],'ro')
plt.show()
exit
... which results with:
xsolv: [ 0.04478625 0.36380344]
... or, on the plot image:
Refs:
Roots finding, Numerical integrations and differential equations - Scipy: Scientific Programming in Python
Is there a python module to solve linear equations? - Stack Overflow

Categories

Resources