I would like to properly change the axes so I can see the values of the x and y components of the two frequencies. I have two sets of code: the first shows the proper data but the axes are wrong, the second shows the proper axes but my two data points are not showing.
First code:
from scipy.fft import fft2, fftshift
import numpy as np
import matplotlib.pyplot as plt
from skimage.filters import window
from scipy.fftpack import fftfreq
k = np.linspace(0,4.76*10,2400)
kx,ky = np.meshgrid(k, k)
x1 = 0.3
y1 = 0.4
x2 = 0.3
y2 = 1
z = 0.05*np.cos(2*np.pi*kx*x1 + 2*np.pi*ky*y1) + 0.05*np.cos(2*np.pi*kx*x2 + 2*np.pi*ky*y2)
wz = z * window('hann', z.shape)
zf = np.abs(fftshift(fft2(wz)))[1200:, 1200:]
plt.figure(1)
plt.axis([0,100, 0,100])
plt.imshow(zf)
plt.show()
And the results are:
The second code:
from scipy.fft import fft2, fftshift
import numpy as np
import matplotlib.pyplot as plt
from skimage.filters import window
from scipy.fftpack import fftfreq
k = np.linspace(0,4.76*10,2400)
kx,ky = np.meshgrid(k, k)
x1 = 0.3
y1 = 0.4
x2 = 0.3
y2 = 1
z = 0.05*np.cos(2*np.pi*kx*x1 + 2*np.pi*ky*y1) + 0.05*np.cos(2*np.pi*kx*x2 + 2*np.pi*ky*y2)
wz = z * window('hann', z.shape)
zf = np.abs(fftshift(fft2(wz)))[1200:, 1200:]
fig, ax = plt.subplots()
ax.set(xlim=(0, 2), ylim=(0, 2))
f = fftfreq(len(k), np.diff(k)[0])
ax.imshow(zf,extent=[0,f[:k.size//2][-1], 0 , f[:k.size//2][-1]])
plt.show()
You need to change the origin in the second example:
ax.imshow(zf, origin='lower', extent=[0,f[:k.size//2][-1], 0 , f[:k.size//2][-1]])
I'm trying to graph this function
=1/4cos**2(θA0 − θB0) + cos**2(θA0 − θB1)+cos**2(θA1 − θB0) + sin**2(θA1 − θB1)
this is my code so far:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
b = np.arange(0, 1, 0)
d = np.arange(0, 1, 0)
B, D = np.meshgrid(A0, B0)
nu = =1/4cos**2(θA0 − θB0) + cos**2(θA0 − θB1)+cos**2(θA1 − θB0) + sin**2(θA1 − θB1)
fig = plt.figure()
ax = Axes3D(fig)
ax.plot_surface(A0, B0, nu)
plt.xlabel('A0')
plt.ylabel('B0')
plt.show()
First, you need to import the math library to use the cosine and sine functions. So, you have to define all your constants and save the "nu" function value one at a time.
I assume A0 and B0 are constant, so you can represent your function in a 2D chart. In this case, the code is:
import matplotlib.pyplot as plt
import numpy as np
import math
# parameters
a0 = 1
a1 = 2
b0 = 3
b1 = 4
t = np.linspace(-(2 * np.pi), 2 * np.pi, 200) # theta
# formula
nu = []
for i in range(len(t)):
nu.append(1/4 * math.cos(t[i]*a0 - t[i]*b0)**2 + math.cos(t[i]*a0 - t[i]*b1)**2 +
math.cos(t[i]*a1 - t[i]*b0)**2 + math.sin(t[i]*a1 - t[i]*b1)**2)
plt.figure()
plt.plot(t, nu, color='red', marker='o')
plt.xlabel('a0')
plt.ylabel('b0')
plt.show()
Otherwise, you can modify A0 and B0 similar to theta and implement a 3D graph.
I've got a question. Below is my code snippet where I am trying to fill a vector given a function yv. When I run the code, there is no error, but it does not print out a result, nor does it show the plot I want.
import matplotlib as plt
import numpy as np
import math as m
e = 2.17
sigma = 1
mu = 0
xv = np.linspace(-4, 4, 100)
for rows in range(0):
for cols in range(100):
yv = 1 / (sigma * (2 * m.pi) ** (-0.5)) * e ** (-0.5) * ((((xv - mu) / sigma)) ** 2)
print('xv= {}'.format(xv))
print('yv= {}'.format(yv))
plt.plot(xv, yv, 'b-o', linewidth = 2, label = 'xv vs. yv')
plt.show()
What am I missing?
Thanks again!
Brandon
Your matplotlib import was not quite right. Try this:
from matplotlib import pyplot as plt
import numpy as np
import math as m
e = 2.17
sigma = 1
mu = 0
xv = np.linspace(-4, 4, 100)
yv = 1/(sigma*(2*m.pi)**(-0.5))*e**(-0.5)*((((xv-mu)/sigma))**2)
print('xv= {}'.format(xv))
print('yv= {}'.format(yv))
plt.plot(xv, yv, 'b-o', linewidth=2, label='xv vs. yv')
plt.show()
What is the best way to create a Sympy equation, do something like take the derivative, and then plot the results of that equation?
I have my symbolic equation, but can't figure out how to make an array of values for plotting. Here's my code:
from sympy import symbols
import matplotlib.pyplot as mpl
t = symbols('t')
x = 0.05*t + 0.2/((t - 5)**2 + 2)
nums = []
for i in range(1000):
nums.append(t)
t += 0.02
plotted = [x for t in nums]
mpl.plot(plotted)
mpl.ylabel("Speed")
mpl.show()
In my case I just calculated the derivative of that equation, and now I want to plot the speed x, so this is fairly simplified.
You can use numpy.linspace() to create the values of the x axis (x_vals in the code below) and lambdify().
from sympy import symbols
from numpy import linspace
from sympy import lambdify
import matplotlib.pyplot as mpl
t = symbols('t')
x = 0.05*t + 0.2/((t - 5)**2 + 2)
lam_x = lambdify(t, x, modules=['numpy'])
x_vals = linspace(0, 10, 100)
y_vals = lam_x(x_vals)
mpl.plot(x_vals, y_vals)
mpl.ylabel("Speed")
mpl.show()
(improvements suggested by asmeurer and MaxNoe)
Alternatively, you can use sympy's plot():
from sympy import symbols
from sympy import plot
t = symbols('t')
x = 0.05*t + 0.2/((t - 5)**2 + 2)
plot(x, (t, 0, 10), ylabel='Speed')
Using SymPy
You can use directly the plotting functions of SymPy:
from sympy import symbols
from sympy.plotting import plot as symplot
t = symbols('t')
x = 0.05*t + 0.2/((t - 5)**2 + 2)
symplot(x)
Most of the time it uses matplotlib as a backend.
Given a mean and a variance is there a simple function call which will plot a normal distribution?
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as stats
import math
mu = 0
variance = 1
sigma = math.sqrt(variance)
x = np.linspace(mu - 3*sigma, mu + 3*sigma, 100)
plt.plot(x, stats.norm.pdf(x, mu, sigma))
plt.show()
I don't think there is a function that does all that in a single call. However you can find the Gaussian probability density function in scipy.stats.
So the simplest way I could come up with is:
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
# Plot between -10 and 10 with .001 steps.
x_axis = np.arange(-10, 10, 0.001)
# Mean = 0, SD = 2.
plt.plot(x_axis, norm.pdf(x_axis,0,2))
plt.show()
Sources:
http://www.johndcook.com/distributions_scipy.html
http://docs.scipy.org/doc/scipy/reference/stats.html
http://telliott99.blogspot.com/2010/02/plotting-normal-distribution-with.html
Use seaborn instead
i am using distplot of seaborn with mean=5 std=3 of 1000 values
value = np.random.normal(loc=5,scale=3,size=1000)
sns.distplot(value)
You will get a normal distribution curve
If you prefer to use a step by step approach you could consider a solution like follows
import numpy as np
import matplotlib.pyplot as plt
mean = 0; std = 1; variance = np.square(std)
x = np.arange(-5,5,.01)
f = np.exp(-np.square(x-mean)/2*variance)/(np.sqrt(2*np.pi*variance))
plt.plot(x,f)
plt.ylabel('gaussian distribution')
plt.show()
Unutbu answer is correct.
But because our mean can be more or less than zero I would still like to change this :
x = np.linspace(-3 * sigma, 3 * sigma, 100)
to this :
x = np.linspace(-3 * sigma + mean, 3 * sigma + mean, 100)
I believe that is important to set the height, so created this function:
def my_gauss(x, sigma=1, h=1, mid=0):
from math import exp, pow
variance = pow(sigma, 2)
return h * exp(-pow(x-mid, 2)/(2*variance))
Where sigma is the standard deviation, h is the height and mid is the mean.
To:
plt.close("all")
x = np.linspace(-20, 20, 101)
yg = [my_gauss(xi) for xi in x]
Here is the result using different heights and deviations:
I have just come back to this and I had to install scipy as matplotlib.mlab gave me the error message MatplotlibDeprecationWarning: scipy.stats.norm.pdf when trying example above. So the sample is now:
%matplotlib inline
import math
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats
mu = 0
variance = 1
sigma = math.sqrt(variance)
x = np.linspace(mu - 3*sigma, mu + 3*sigma, 100)
plt.plot(x, scipy.stats.norm.pdf(x, mu, sigma))
plt.show()
you can get cdf easily. so pdf via cdf
import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate
import scipy.stats
def setGridLine(ax):
#http://jonathansoma.com/lede/data-studio/matplotlib/adding-grid-lines-to-a-matplotlib-chart/
ax.set_axisbelow(True)
ax.minorticks_on()
ax.grid(which='major', linestyle='-', linewidth=0.5, color='grey')
ax.grid(which='minor', linestyle=':', linewidth=0.5, color='#a6a6a6')
ax.tick_params(which='both', # Options for both major and minor ticks
top=False, # turn off top ticks
left=False, # turn off left ticks
right=False, # turn off right ticks
bottom=False) # turn off bottom ticks
data1 = np.random.normal(0,1,1000000)
x=np.sort(data1)
y=np.arange(x.shape[0])/(x.shape[0]+1)
f2 = scipy.interpolate.interp1d(x, y,kind='linear')
x2 = np.linspace(x[0],x[-1],1001)
y2 = f2(x2)
y2b = np.diff(y2)/np.diff(x2)
x2b=(x2[1:]+x2[:-1])/2.
f3 = scipy.interpolate.interp1d(x, y,kind='cubic')
x3 = np.linspace(x[0],x[-1],1001)
y3 = f3(x3)
y3b = np.diff(y3)/np.diff(x3)
x3b=(x3[1:]+x3[:-1])/2.
bins=np.arange(-4,4,0.1)
bins_centers=0.5*(bins[1:]+bins[:-1])
cdf = scipy.stats.norm.cdf(bins_centers)
pdf = scipy.stats.norm.pdf(bins_centers)
plt.rcParams["font.size"] = 18
fig, ax = plt.subplots(3,1,figsize=(10,16))
ax[0].set_title("cdf")
ax[0].plot(x,y,label="data")
ax[0].plot(x2,y2,label="linear")
ax[0].plot(x3,y3,label="cubic")
ax[0].plot(bins_centers,cdf,label="ans")
ax[1].set_title("pdf:linear")
ax[1].plot(x2b,y2b,label="linear")
ax[1].plot(bins_centers,pdf,label="ans")
ax[2].set_title("pdf:cubic")
ax[2].plot(x3b,y3b,label="cubic")
ax[2].plot(bins_centers,pdf,label="ans")
for idx in range(3):
ax[idx].legend()
setGridLine(ax[idx])
plt.show()
plt.clf()
plt.close()
import math
import matplotlib.pyplot as plt
import numpy
import pandas as pd
def normal_pdf(x, mu=0, sigma=1):
sqrt_two_pi = math.sqrt(math.pi * 2)
return math.exp(-(x - mu) ** 2 / 2 / sigma ** 2) / (sqrt_two_pi * sigma)
df = pd.DataFrame({'x1': numpy.arange(-10, 10, 0.1), 'y1': map(normal_pdf, numpy.arange(-10, 10, 0.1))})
plt.plot('x1', 'y1', data=df, marker='o', markerfacecolor='blue', markersize=5, color='skyblue', linewidth=1)
plt.show()
For me, this worked pretty well if you are trying to plot a particular pdf
theta1 = {
"a": 0.5,
"cov" : 1,
"mean" : 0
}
x = np.linspace(start = 0, stop = 1000, num = 1000)
pdf = stats.norm.pdf(x, theta1['mean'], theta1['cov']) + theta2['a']
sns.lineplot(x,pdf)