I have a function u(x,y,z,t) and I wanted to plot (x,y) animated heatmap with colorbar (u_min, u_max) where t is parameter for time animation. I've analyzed the examples, but it looks complicated. The z parameter will be constant. The defined u(x,y,z,t) is the equation
u(x,y,z,t).
I made this
import matplotlib.pyplot as plt
import numpy as np
def u(x, y, z, t):
alpha = 9*10**-6
a = 0.01
z = a/2
for i in range(1,k):
sin1 = np.sin((i*np.pi*x)/a)
sin2 = np.sin((i*np.pi*y)/a)
sin3 = np.sin((i*np.pi*z)/a)
e = np.exp(-((alpha**2)*(np,pi**2)*((n**2)*(m**2)*(l**2))*t/a**2)
a_n = 80*(2/np.pi)**3*(1/n*m*l)*(1-(-1)**n)*(1-(-1)**m)*(1-(-1)**l)
u += 20 + a_n*sin1*sin2*sin3*e
return u
data = u
fig, ax = plt.subplots()
for j in range(len(data)):
ax.cla()
ax.imshow(data[j])
ax.set_title("frame {}".format(i))
plt.pause(0.1)
Thank you for help.
Related
I'm trying to create a vector field and some curve, I've created a vector field as shown
import matplotlib.pyplot as plt
import numpy as np
x,y = np.meshgrid(np.arange(-3,3,.35),np.arange(-3,3,.35))
u = x
v = y
plt.quiver(x, y, u, v, color = 'black')
plt.show()
But I want to add the curve $y=x^2$ in the same plot, how could I do that?
I've tryeid to add plt.plot and the curve but the result is weird.
You probably want to keep the y-axis limit as was in the mesh grid. plt.ylim is helpful in that case
import matplotlib.pyplot as plt
import numpy as np
x, y = np.meshgrid(np.arange(-3, 3, .35), np.arange(-3, 3, .35))
u = x
v = y
plt.quiver(x, y, u, v, color = 'black')
x = np.linspace(-3, 3, 100)
ylim = plt.ylim()
plt.plot(x, x**2)
plt.ylim(ylim)
plt.show()
Output:
Let's assume I have 3 arrays defined as:
v1=np.linspace(1,100)
v2=np.linspace(1,100)
v3=np.linspace(1,100)
Then I have a function that takes those 3 values and gives me the desired output, let's assume it is like:
f = (v1 + v2*10)/v3
I want to plot that function on a 3D plot with axis v1,v2,v3 and color it's surface depending on its value.
More than the best way to plot it, I was also interested in how to scroll all the values in the in vectors and build the function point by point.
I have been trying with for loops inside other for loops but I am always getting one error.
MANY THANKS
I tried this but i'm always getting a line instead of a surface
import mpl_toolkits.mplot3d.axes3d as axes3d
import sympy
from sympy import symbols, Function
# Parameters I use in the function
L = 132
alpha = 45*math.pi/180
beta = 0
s,t = symbols('s,t')
z = Function('z')(s,t)
figure = plt.figure(figsize=(8,8))
ax = figure.add_subplot(1, 1, 1, projection='3d')
# experiment with various range of data in x and y
x1 = np.linspace(-40,-40,100)
y1 = np.linspace(-40,40,100)
x,y = np.meshgrid(x1,y1)
# My function Z
c1=math.cos(beta)**2
c2=math.cos(alpha)**2
s1=math.sin(alpha)**2
den = math.sqrt((c1*c2)+s1)
z=L*((math.cos(beta)/den)-1)+(s*(math.sin(alpha)))+(t*(1-math.cos(alpha)))
ax.plot_surface(x,y,z,cmap='rainbow')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.show()
In this example I'm going to show you how to achieve your goal. Specifically, I use Numpy because it supports vectorized operations, hence I avoid for loops.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize
import matplotlib.cm as cm
# Parameters I use in the function
L = 132
alpha = 45*np.pi/180
beta = 0
figure = plt.figure()
ax = figure.add_subplot(1, 1, 1, projection='3d')
# experiment with various range of data in x and y
x1 = np.linspace(-40,40,100)
y1 = np.linspace(-40,40,100)
x,y = np.meshgrid(x1,y1)
# My function Z
c1=np.cos(beta)**2
c2=np.cos(alpha)**2
s1=np.sin(alpha)**2
den = np.sqrt((c1*c2)+s1)
z=L*((np.cos(beta)/den)-1)+(x*(np.sin(alpha)))+(y*(1-np.cos(alpha)))
# compute the color values according to some other function
color_values = np.sqrt(x**2 + y**2 + z**2)
# normalize color values between 0 and 1
norm = Normalize(vmin=color_values.min(), vmax=color_values.max())
norm_color_values = norm(color_values)
# chose a colormap and create colors starting from the normalized values
cmap = cm.rainbow
colors = cmap(norm_color_values)
surf = ax.plot_surface(x,y,z,facecolors=colors)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
# add a colorbar
figure.colorbar(cm.ScalarMappable(norm=norm, cmap=cmap), label="radius")
plt.show()
I want to draw a circle in the XZ plane. The middlepoint of the circle should be coincide with the green spot.
Unfortunately i can´t find a way to draw the circle in the XZ-Plane (only in XY-plane). The center of the circle is (0,0).
Do you have an idea to draw the circle in the XZ-Plane?
That´s the code:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
def singular_value_decomposition(X):
import numpy as np
C = np.average(X,axis=0)
print(C)
CX = X-C
U,S,V = np.linalg.svd(CX)
return C,V
def cloud():
import numpy as np
h = 0.5*(1+np.sqrt(5))
p1 = np.array([[0,1,h],[0,1,-h],[0,-1,-h]])
p2 = p1[:,[1,2,0]]
p3 = p1[:,[0,1,2]]
return np.vstack((p1,p2,p3))
A = cloud()
print(A)
centroid, V = singular_value_decomposition(A)
# calculate a circle
theta = np.linspace(0, 2*np.pi, 100)
r = np.sqrt(0.5)
x1 = r*np.cos(theta)
x2 = r*np.sin(theta)
# plot graph
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(centroid[0], centroid[1], centroid[2], color='green',s=100)
#draw circle
ax.plot(x1,x2)
ax.set_xlabel('$X$',fontsize=20)
ax.set_ylabel('$Y$',fontsize=20)
ax.set_zlabel('$Z$', fontsize=20)
plt.show()
I have a issue to interpolate my values "c" on cylindrical surface.
The problem is that possibly I dont understand how to indicate surface for gridding with gridddata function..
>import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata as gd
#Creating data in polar coordinates
phi,d = np.linspace(0, 2* np.pi, 20), np.linspace(0,20,20)
PHI,D = np.meshgrid(phi,d)
R = 2
#Transforming in X Y Z coordinates
X = R * np.cos(PHI)
Y = R * np.sin(PHI)
Z = R * D
T=np.linspace(0,10,400)
c=np.sin(T)*np.cos(T/2) #Value c I would like to interpolate
fig1 = plt.figure()
ax = fig1.add_subplot(1,1,1, projection='3d')
xi=np.array(np.meshgrid(X,Y,Z))
img = ax.scatter(X, Y, Z,c=c, cmap=plt.hot()) #To plot data scatter before interpolation
fig1.colorbar(img)
plt.show()
X1,Y1,Z1 =np.meshgrid(X ,Y ,Z) #To define sufrace for interpolation
int = gd((X,Y,Z), c, (X1,Y1,Z1), method='linear')
fig2 = plt.figure() #trying to plot the answer
ax1 = fig2.add_subplot(1,1,1, projection='3d')
ax1.scatter(int)
img = ax1.scatter(X, Y, Z, c=c, cmap=plt.hot())
`
Its gives error: different number of values and points
I dont know how to indicate (X1,Y1,Z1) surface in griddata function
Thanks a lot for any tips ...
In matplotlib, it's easy to draw a line from data points with plt.plot(xs, ys, '-'+marker). This gets you an undirected line, where you can't tell from looking at the resulting diagram, which end corresponds to the beginning of the arrays of data points and which to the end of the arrays. It happens that for what I'm doing, it's important to be able to tell which end is which, or equivalently, which direction the line is going. What is the recommended way to plot a line so as to obtain that visual distinction?
The following would be one option. It is to add some arrow heads along a line. This can be done using a FancyArrowPatch.
import numpy as np ; np.random.seed(7)
import matplotlib.pyplot as plt
from matplotlib.patches import FancyArrowPatch
class RL(object):
def __init__(self, n, d, s=0.1):
a = np.random.randn(n)*s
a[0] = np.random.rand(1)*np.pi*2
self.xy = np.random.rand(n,2)*5
self.xy[1,:] = self.xy[0,:] + np.array([d*np.cos(a[0]),d*np.sin(a[0])])
for i in range(2,n):
(x,y), = np.diff(self.xy[i-2:i,:], axis=0)
na = np.arctan2(y,x)+a[i]
self.xy[i,:] = self.xy[i-1,:] + np.array([d*np.cos(na),d*np.sin(na)])
self.x = self.xy[:,0]; self.y = self.xy[:,1]
l1 = RL(1000,0.005)
l2 = RL(1000,0.007)
l3 = RL(1000,0.005)
fig, ax = plt.subplots()
ax.set_aspect("equal")
ax.plot(l1.x, l1.y)
ax.plot(l2.x, l2.y)
ax.plot(l3.x, l3.y)
ax.plot(l1.x[0], l1.y[0], marker="o")
def arrow(x,y,ax,n):
d = len(x)//(n+1)
ind = np.arange(d,len(x),d)
for i in ind:
ar = FancyArrowPatch ((x[i-1],y[i-1]),(x[i],y[i]),
arrowstyle='->', mutation_scale=20)
ax.add_patch(ar)
arrow(l1.x,l1.y,ax,3)
arrow(l2.x,l2.y,ax,6)
arrow(l3.x,l3.y,ax,10)
plt.show()