How to project the intersection point of a plot with a line? - python

I am looking for a way to project the intersection point of the graph using a vertical discontinuous line (style '--') on the x-axis and then write the x-coordinate on that axis.
Here's my attempt to find the intersection. For some reason, the point is not exactly on the intersection. It's strange.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
n = 256
k = np.arange(0, 100)
g = 1 - np.exp(-0.5 * k * (k - 1) / n)
plt.plot(g, '-')
plt.hlines(0.5, 0, 100, 'r')
idx = np.argwhere(np.diff(np.sign(g - 0.5)))
plt.plot(k[idx], g[idx], 'o')
plt.show()

As mentioned in the comment by tevemadar you need to find the intersection point by solving for k for g = 0.5 i.e where you've drawn your hline.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
n = 256
k = np.arange(0, 100)
f = 0.5
g = 1 - np.exp(-0.5 * k * (k - 1) / n)
plt.plot(g, '-')
hline_pos = 0.5
plt.hlines(hline_pos, 0, 100, 'r')
# inverse
# np.exp(-0.5 * k * (k - 1) / n) = 1 - g
# -0.5 * k * (k - 1) / n = np.log(1 - g)
# k^2 - k = np.log(1 - g) * (-n/0.5)
solve_for = hline_pos
constant = np.log(1 - solve_for) * (-n/0.5)
ks = np.roots([1, -1, -constant])
ks = np.sort(ks) # sort to get the positive root based on the domain boundaries
plt.scatter(ks[1], hline_pos)
plt.vlines(ks[1], 0, hline_pos, linestyles='--')
plt.show()

Related

How could I make a line which is inverted to the original

At the moment this is my code:
import scipy
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import EventCollection
import math
from scipy import integrate
from scipy import constants
K_b = 1.380649e-23 # Boltzmanns Constant
a_n = 6.022e23 # Avogrados Number
T = 10 # Kelvin
mass = 28
a = 10e-5
def mantleEvolution(tMax, dt) :
N = int(tMax/dt) + 1
timeArray = np.zeros(N)
numberArray = np.zeros(N)
t = 0
n_m = 1 #per cubic centimeter
n_s = 0
i = 0
while i < N:
m_m = float(mass) / a_n
V_m = math.sqrt((8.0 * K_b * float(T)) / (math.pi * float(m_m)))
R = math.pi * pow(float(a), 2) * n_m * V_m
ρ_d = 3 # g/cm^3
μ_g = 2 * 1.67e-23
m_d = (4 / 3) * math.pi * pow(float(a), 3)
n_g = 10e4
d_g = 0.01 # 1% mass density of gas
n_d = (d_g * n_g * μ_g) / (m_d * float(ρ_d))
n_s = n_s + R * dt
n_m = n_m - R * n_d * dt
timeArray[i] = t
numberArray[i] = n_m
t = t + dt
i = i + 1
return [timeArray, numberArray, n_s]
timeArray, numberArray, n_s = mantleEvolution(5.0 * 10**15, 5.0 * 10**9)
fig = plt.figure(figsize=(6.4, 6.4))
ax1 = plt.subplot(111)
ax1.plot(timeArray, numberArray)
ax1.set_xlabel('time, seconds', fontsize=20)
ax1.set_ylabel('number', fontsize=20)
plt.setp(ax1.get_xticklabels(), fontsize=16)
plt.setp(ax1.get_yticklabels(), fontsize=16)
fig.subplots_adjust(left=.18)
plt.savefig('mantleEvolution.pdf')
This is the graph I recieve from graphing my code:
What I wish to find out is how I could plot a second line which behaves the exact opposite where it grows at the same rate the other declines
So for example, something that ressembles this:
If you look at the graph you'll see that the value on the y axis is for both graphs the same for two opposite x values at the x axis. That means that all you want to do is invert the x axis. That is fairly easy done using the formula:
new_x = -1 * (old_x - 2.5) + 2.5
By the way, I see some interesting comments in your code. What is it that you are trying to do here if I may ask?

only size-1 arrays can be converted to Python scalars: Trying to plot circular orbit with equation of. circle

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!

1D FitzHugh Nagumo model

I am going to solve 1D FitzHugh Nagoma with homogeneous Neumann boundary conditions.
How to plot U and V separately. Here a1=2, a0=-0.03 , ep= 0.01 Du= 1, Dv=4 I was confused by plotting the figure
U_t=Du U_xx +U -U^3 - V
V_t=Dv V_xx + ep(U-a1V - a0)
import numpy as np
import matplotlib.pyplot as plt
#matplotlib inline
Du = 0.001
Dv = 0.005
tau = 1
k = -.00
ep = 0.01
a1 = 2
a0 = -0.03
L = 2
N= 10
x = np.linspace(0, L, N+1)
dx = x[1]-x[0]
T = 45 # total time
dt = .01 # time step
size = N
n = int(T / dt) # number of iterations
U = np.random.rand(size)
V = np.random.rand(size)
def laplacian(Z):
Ztop = Z[0:-2]
Zbottom = Z[2:]
Zcenter = Z[1:-1]
return (Ztop + Zbottom -
2 * Zcenter) / dx**2
def show_patterns(U, ax=None):
ax.imshow(U, cmap=plt.cm.copper,
interpolation='bilinear',
extent=[-1, 1])
ax.set_axis_off()
fig, axes = plt.subplots(3, 3, figsize=(16, 16))
step_plot = n // 9
# We simulate the PDE with the finite difference
# method.
for i in range(n):
# We compute the Laplacian of u and v.
deltaU = laplacian(U)
deltaV = laplacian(V)
# We take the values of u and v inside the grid.
Uc = U[1:-1]
Vc = V[1:-1]
# We update the variables.
U[1:-1], V[1:-1] = \
Uc + dt * (Du * deltaU + Uc - Uc**3 - Vc),\
Vc + dt * (Dv * deltaV + ep*(Uc - a1*Vc - a0)) / tau
# Neumann conditions: derivatives at the edges
# are null.
for Z in (U, V):
Z[0] = Z[1]
Z[-1] = Z[-2]
# Z[:, 0] = Z[:, 1]
# Z[:, -1] = Z[:, -2]
# We plot the state of the system at
# 9 different times.
fig, ax = plt.subplots(1, 1, figsize=(8, 8))
show_patterns(U,ax=None)
I got an error 'NoneType' object has no attribute 'imshow'
and could not solve it
This line
show_patterns(U,ax=None)
passed in a None to the ax parameter.
I don't know what ax should be but it needs to be properly initialised.

Adding the output of one graph to another graph

I would like to find a way to translate and add the bottom graph (from y = -20 to 0) onto the above graph (from y = 0-20) so that the final domain is between y = 0 to 20:
However, I am finding problems doing it, as the graph I used to draw the bottom graph (R12) has already a negative input, thus it will not show up on the positive y-axis. Here is my code:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
N = 1001
lower = 0
upper = 20
u = np.linspace(lower, upper, N)
t1a, t3a = np.meshgrid(u,-u)
t1, t3 = np.meshgrid(u,u)
omega = 10
delta = 5
tau = 2
mu = 1
t2 = 0.1
def g(t):
return delta * (omega ** 2) * (tau ** 2) * ((np.e ** (-t/tau))+(t/tau)-1)
R12 = 1 * (mu ** 4) * (np.e **(-1j * omega * (t3a-(t1a)))) * (np.e ** (-g(t1a)+g(t2)-g(t3a)-g(t1a+t2)-g(t2+t3a)+g(t1a+t2+t3a)))
R45 = 1 * (mu ** 4) * (np.e ** (-1j * omega * (t3+t1))) * (np.e ** (-g(t1)-g(t2)-g(t3)+g(t1+t2)+g(t2+t3)-g(t1+t2+t3)))
R12_fft = np.fft.fftshift((np.fft.fft2((R12)))) / np.sqrt(len(R12))
R45_fft = np.fft.fftshift((np.fft.fft2((R45)))) / np.sqrt(len(R45))
R_pure = (R12_fft + R45_fft)
plt.contourf(t1a,t3a,R12_fft, cmap = 'seismic')
plt.contourf(t1,t3,R45_fft, cmap = 'seismic')
plt.xlabel('${\omega}_{3}$', fontsize = 24)
plt.ylabel('${\omega}_{1}$', fontsize = 24)
plt.xlim(-20, 20)
plt.ylim(-20, 20)
plt.gca().set_aspect('equal', adjustable='box')
plt.colorbar()
plt.show()
As an example, if I try to do the simple adding:
plt.contourf(t1,t3,R_pure, cmap = 'seismic')
it basically gives me back the same shape of the graph. What I would like instead is superimposing the bottom graph onto the top and adding the output together. Is there any way I can achieve this? Thank you!
I feel like it's a bit too dumb, so it's probably wrong.
R_pure = (R12_fft + abs(R45_fft))

Python: Plotting Bessel functions of the first kind with a float argument

The equation I am working with is
$$
E = M_e + \sum_{n = 1}^N\frac{2}{n}\mathcal{J}_n(ne)\sin(nM_e)
$$
where $\mathcal{J}_n(x)$ is the nth Bessel function of the first kind.
As a test, I plotted the first 6 Bessel functions and everything worked out correctly. When I enter the argument of $n * e$, the plot isn't what I anticipated it to be.
import numpy as np
import pylab as py
import scipy.special as sp
x = np.linspace(0, 15, 500000)
for v in range(0, 6):
py.plot(x, sp.jv(v, x))
py.xlim((0, 15))
py.ylim((-0.5, 1.1))
py.legend(('$\mathcal{J}_0(x)$', '$\mathcal{J}_1(x)$', '$\mathcal{J}_2(x)$',
'$\mathcal{J}_3(x)$', '$\mathcal{J}_4(x)$', '$\mathcal{J}_5(x)$'),
loc = 0)
py.xlabel('$x$')
py.ylabel('$\mathcal{J}_n(x)$')
#py.title('Plots of the first six Bessel Functions')
py.grid(True)
#py.savefig('besseln0to6.eps', format = 'eps')
py.show()
e = 0.99
def E(M):
return (M + sum(2.0 / n * sp.jv(n * e, M) * np.sin(n * M)
for n in range(1, 3, 1)))
M = np.linspace(0, 2 * np.pi, 500000)
fig2 = py.figure()
ax2 = fig2.add_subplot(111, aspect = 'equal')
ax2.plot(E(M), M, 'b')
def E2(M):
return (M + sum(2.0 / n * sp.jv(n * e, M) * np.sin(n * M)
for n in range(1, 11, 1)))
ax2.plot(E2(M), M, 'r')
py.xlim((0, 2 * np.pi))
py.ylim((0, 2 * np.pi))
py.xlabel('Eccentric anomaly, $E$')
py.ylabel('Mean anomaly, $M_e$')
py.show()
The plot is supposed to look like for n = 10
The problem is the use of the Bessel function sp.jv(n * e, M) whereas it should be order, argument. That in turn leads to sp.jv(n , n * e) which generates the correct plot.

Categories

Resources