I have trouble with plt.contourf.
The program is supposed to calculate the distance between s1 and m called s1m and S2 and m called s2m than using s1m and s2m we calculate the wave functions psi and psiP than we multiply them to get the intensity of light, we use what we get in contourf to see the results in a screen.
When I run the program I
import numpy as np
import matplotlib.pyplot as plt
S1 = np.array([100,0,-1])
S2 = np.array([-100,0,-1])
M = np.array([1,1,0])
Lambda = 633
s1m= np.substract(m,S1)#vector S1M
s2m= np.substract(m,S2)#vector S2M
SM1= np.multiply(s1m,s1m)
SM2= np.multiply(s2m,s2m)
S1M= np.sqrt(SM1)#distance s1m
S2M= np.sqrt(SM2)#distance s2m
def intensity (S1M,S2M):
Phi1=(2 * np pi * S1M)/lambda
Phi2=(2 * np.pi * S2M)/lambda
Tet1=(-2 * np.pi * S1M)/lambda
Tet2=(-2 * np.pi * S2M)/lambda
Psi1 = np.exp(Phi1)
Psi2 = np.exp(Phi2)
Psi1P = np.exp(Tet1)
Psi2P = np.exp(Tet2)
Psi = Psi1 + Psi2
PsiP = Psi1P + Psi2P
I = Psi * PsiP
x = np.linspace(1,5,5)
y = np.linspace(1,5,5)
XX,YY = np.meshgrid(x,y)
ZZ = intensity (S1M, S2M)
plt.contourf (XX, YY, ZZ)
plt.show()
Related
I'm relatively new to python so forgive me for any nonsense in my code. I am trying to program a circular orbit of a planet (I just used the mass of Uranus and the Sun) in python using equations from my Classical Mechanics textbook (John R. Taylor's Classical Mechanics). I figured I could just use the equations and graph a function, y, that equals the equations of a circle with c_squared being the radius and x being an array of values being used to plot the circle. Let me know how I can improve the code or I am even going in the right direction.
...
import matplotlib.pyplot as plt
import numpy as np
import matplotlib
import math
fig = plt.figure()
ax = fig.add_subplot()
m_uranus = 8.681 * 10**(25)
m_sun = 1.989 * 10 **(30)
G = 6.67430 * 10**(-11)
mu = (m_uranus * m_sun)/(m_uranus + m_sun)
l = (1.7 * 10**(42)) * 1000 * 24 * 60 * 60
ang_squared = l ** 2
c = (ang_squared)/(G * m_uranus * m_sun * mu)
c_squared = c**2
print(m_sun, mu, m_uranus, ang_squared, c)
x = np.arange(-100, 100, 1)
y = math.sqrt(c_squared - x)
plt.plot(x, y)
plt.show()
...
As mentioned by #JohanC, use numpy np.sqrt() instead of math.sqrt() will fix your error, here the fix with (unnecessary libraries removed):
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot()
m_uranus = 8.681 * 10 ** 25
m_sun = 1.989 * 10 ** 30
G = 6.67430 * 10 ** (-11)
mu = (m_uranus * m_sun) / (m_uranus + m_sun)
l = (1.7 * 10 ** 42) * 1000 * 24 * 60 * 60
ang_squared = l ** 2
c = ang_squared / (G * m_uranus * m_sun * mu)
c_squared = c ** 2
print(m_sun, mu, m_uranus, ang_squared, c)
x = np.arange(-100, 100, 1)
y = np.sqrt(c_squared - x)
plt.plot(x, y)
plt.show()
Hope, this will help you by!
This is a code for generating random sized spheres with mayavi,
I want to make the spheres to be connected with each other by the surface or with a bond line:
Spheres must be at random positions in 3D space
Spheres must be with the same radius
from mayavi import mlab
import numpy as np
[phi,theta] = np.mgrid[0:2*np.pi:12j,0:np.pi:12j]
x = np.cos(phi)*np.sin(theta)
y = np.sin(phi)*np.sin(theta)
z = np.cos(theta)
def plot_sphere(p):
r,a,b,c = p
r=1
return mlab.mesh(r*x+a, r*y+b, r*z )
for k in range(8):
c = np.random.rand(4)
c[0] /= 10.
plot_sphere(c)
mlab.show()
From sphere equation:
So when passing arguments to mlab.mesh we would like to set [x_0, y_0, z_0] for each sphere such as they are at different positions from the axis.
The problem was that the numbers generated by np.random.rand(4) are random, but not distinct.
Let's modify so that the arguments [x_0, y_0, z_0] are random and distinct:
We use sample to get distinct index numbers in a cube
We convert using index_to_3d the index to an (x, y, z) coordinates
The radius, r, can be adjusted to have more or less spacing between the spheres.
Spheres at 3D space
Code:
import random
from itertools import product
from mayavi import mlab
import numpy as np
[phi, theta] = np.mgrid[0:2 * np.pi:12j, 0:np.pi:12j]
x = np.cos(phi) * np.sin(theta)
y = np.sin(phi) * np.sin(theta)
z = np.cos(theta)
def plot_sphere(x_0, y_0, z_0):
r = 0.5
return mlab.mesh(r * x + x_0, r * y + y_0, r * z + z_0)
SPHERES_NUMBER = 200
CUBE_SIZE = 10
def index_to_3d(i, SIZE):
z = i // (SIZE * SIZE)
i -= (z * SIZE * SIZE)
y = i // SIZE
x = i % SIZE
return x, y, z
random_tuples = [index_to_3d(i, CUBE_SIZE) for i in random.sample(range(CUBE_SIZE ** 3), SPHERES_NUMBER)]
for k in range(SPHERES_NUMBER):
x_0, y_0, z_0 = random_tuples[k]
plot_sphere(x_0, y_0, z_0)
mlab.show()
Output:
Spheres cluster
Let's utilize gauss to create coordinates for the cluster points.
Code:
import random
from itertools import product
from mayavi import mlab
import numpy as np
[phi, theta] = np.mgrid[0:2 * np.pi:12j, 0:np.pi:12j]
x = np.cos(phi) * np.sin(theta)
y = np.sin(phi) * np.sin(theta)
z = np.cos(theta)
def plot_sphere(x_0, y_0, z_0):
r = 0.5
return mlab.mesh(r * x + x_0, r * y + y_0, r * z + z_0)
SPHERES_NUMBER = 200
def create_cluster(CLUSTER_SIZE):
means_and_deviations = [(1, 1.5), (1, 1.5), (1, 1.5)]
def generate_point(means_and_deviations):
return tuple(random.gauss(mean, deviation) for mean, deviation in means_and_deviations)
cluster_points = set()
while len(cluster_points) < CLUSTER_SIZE:
cluster_points.add(generate_point(means_and_deviations))
return list(cluster_points)
cluster_points = create_cluster(SPHERES_NUMBER)
for k in range(SPHERES_NUMBER):
x_0, y_0, z_0 = cluster_points[k]
plot_sphere(x_0, y_0, z_0)
mlab.show()
Output:
What about just using the mayavi points3d function? By default the mode parameter is set to sphere and you can set the diameter by using the scale_factor parameter. You can also increase the resolution of the sphere by varying the resolution parameter.
Here is the code:
def draw_sphere(
center_coordinates,
radius,
figure_title,
color,
background,
foreground
):
sphere = mlab.figure(figure_title)
sphere.scene.background = background
sphere.scene.foreground = foreground
mlab.points3d(
center_coordinates[0],
center_coordinates[1],
center_coordinates[2],
color=color,
resolution=256,
scale_factor=2*radius,
figure=sphere
)
Regarding the connected with each other by the surface issue, your explanation is poor. Maybe you mean just tangent spheres, but I would need more details.
I am looking for the points of intersection of a vertical line with a plot that I have made that has pyplot's interpolated values.
I think the code and plot below will make my question more clear. Below is some example code, and the resulting plot. What I am looking for is all intersection points between the red vertical line and the blue lines (so there should be 3 such points in this case).
I am at a loss for how to do this - does anyone know how?
The code:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
t = np.linspace(-np.pi, np.pi, 512, endpoint=False) + 0.0001 # 0.0001 to get rid of 0 values.
# normalized square wave
u = np.sign(np.sin(2 * np.pi * t))
u = u - np.min(u)
u = u / np.max(u)
# rotate the square wave
phi = - np.pi / 3.0
t_rot = t * np.cos(phi) - u * np.sin(phi)
u_rot = u * np.cos(phi) + t * np.sin(phi)
# level the rotated square wave
u_rot_leveled = u_rot + np.tan(-phi) * t_rot
plt.plot(t_rot, u_rot_leveled, '.-')
plt.axvline(x=-1.1, linestyle=':', color='red')
The plot:
Thanks for any help!
Instead of interpolating the values of y where x==x0, you may actually find the roots(zeros) of x-x0 with respect to y.
import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(-np.pi, np.pi, 512, endpoint=False) + 0.0001 # 0.0001 to get rid of 0 values.
# normalized square wave
u = np.sign(np.sin(2 * np.pi * t))
u = u - np.min(u)
u = u / np.max(u)
# rotate the square wave
phi = - np.pi / 3.0
t_rot = t * np.cos(phi) - u * np.sin(phi)
u_rot = u * np.cos(phi) + t * np.sin(phi)
# level the rotated square wave
u_rot_leveled = u_rot + np.tan(-phi) * t_rot
def find_roots(x,y):
s = np.abs(np.diff(np.sign(y))).astype(bool)
return x[:-1][s] + np.diff(x)[s]/(np.abs(y[1:][s]/y[:-1][s])+1)
x0 = -1.1
z = find_roots(u_rot_leveled, t_rot-x0)
plt.plot(t_rot, u_rot_leveled, '.-')
plt.axvline(x=x0, linestyle=':', color='red')
plt.plot(np.ones_like(z)*x0, z, marker="o", ls="", ms=4, color="limegreen")
plt.show()
Part of the solution here is taken from my answer to How to get values from a graph?
I am trying to crate a program that randomly generates line segments using parametric equations. What I have created kinds of does the job, but instead of the lines being disconnected from one another they form one continues line. This is what I have written in python.
enter import numpy as np
import random as rand
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_aspect("equal")
npoints = 10
V = np.zeros(npoints)
def point1 (npoints):
x0 = np.zeros(npoints)
y0 = np.zeros(npoints)
z0 = np.zeros(npoints)
for k in range (npoints):
theta = rand.uniform(0.0, np.pi)
phi = rand.uniform(0.0, (2 * np.pi))
x0[k] = 10 * np.sin(phi) * np.cos(theta)
y0[k] = 10 * np.sin(phi) * np.sin(theta)
z0[k] = 10 * np.cos(theta)
return np.array([x0,y0,z0])
def point2 (npoints):
x1 = np.zeros(npoints)
y1 = np.zeros(npoints)
z1 = np.zeros(npoints)
for j in range (npoints):
theta = rand.uniform(0.0, np.pi)
phi = rand.uniform(0.0, (2 * np.pi))
x1[j] = 10 * np.sin(phi) * np.cos(theta)
y1[j] = 10 * np.sin(phi) * np.sin(theta)
z1[j] = 10 * np.cos(theta)
return np.array([x1,y1,z1])
n = 10
def t_parameter(n):
t = np.zeros(n)
for i in range (n):
t[i] = rand.uniform(-10,10)
return np.array([t])
p1 = point1(npoints)
p2 = point2(npoints)
V = p2-p1
d = t_paramiter(n)
Lx = d*V[0]+p1[0]
Ly = d*V[1]+p1[1]
Lz = d*V[2]+p1[2]
ax.plot_wireframe(Lx,Ly,Lz)
When I run the code this is what is generated plot of what is generated. What I would like to code to do is keep the values of the initial point and direction vector constant while just updating the d with random values.
I have tried doing something like this
Lx = np.zeros(npoints)
Ly = np.zeros(npoints)
Lz = np.zeros(npoints)
for i in range (n):
Lx[i] = d[i]*V[i]+p1[i]
Ly[i] = d[i]*V[i]+p1[i]
Lz[i] = d[i]*V[i]+p1[i]
but I get an error "setting an array element with a sequence".
How can I remove the asymptote?
import numpy as np
e = 1.26
beta = .705 * np.pi
rph = 7000
re = 6378
def r(nuh):
return rph * (1 + e) / (1 + e * np.cos(nuh + beta))
theta = np.linspace(-np.pi, np.pi, 50000)
fig2 = pylab.figure()
ax2 = fig2.add_subplot(111)
ax2.plot(r(theta) * np.cos(theta), r(theta) * np.sin(theta))
ax2.plot(rph * np.cos(theta), rph * np.sin(theta), 'r')
# adding the Earth
earth2 = pylab.Circle((0, 0), radius = re, color = 'b')
ax2.add_patch(earth2)
pylab.xlim((-50000, 100000))
pylab.ylim((-50000, 100000))
pylab.show()
As you can see here, setting the divergent points to np.nan will cause them not to be plotted.
In your problem, it is r(theta) which diverges. Define r and theta in the usual way, but then, you want to set the extrema of r(theta) to np.nan.
To do this, make an array first, then change its extrema to np.nan:
rt = r(theta)
ext = [np.argmin(rt), np.argmax(rt)]
rt[ext] = np.nan
Now, be sure to plot with the modified rt array not the original function:
ax2.plot(rt * np.cos(theta), rt * np.sin(theta))