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()
Related
How can i do this equation with library Matplotlib?
f(x) = exp(sqrt(x))/2 - sqrt(x**3)/5 + 2
import matplotlib as plt
import numpy as np
import math
fig, (ax1) = plt.subplots(nrows=2)
x = np.linspace(-3, 3, 100)
ax1.plot(x, 0.5.np.exp)
plt.show()
This represents your equation, but please double check it.
import math
e1 = lambda x: 0.5 * math.exp(-1 * math.sqrt(x)) - (0.2 * math.sqrt(x^3)) + 2
e1(1) # 1.901097008111102
I have been trying to get a plot of vector lines going using the matplotlib library and I keep getting something like this:
Not sure what is happening since the code I'm running seems to follow the syntax for how to make a basic quiver plot. I've tried messing with the array type to see if that's the issue but no luck. Some points on the plot just don't seem to be getting any vector data.
import matplotlib.pyplot as plt
import numpy as np
X = np.arange(-2,2,.1)
Y = np.arange(-2,2,.1)
x,y = np.meshgrid(X,Y)
m1 =1
m2 =2
x1 =4/3
x2 =2/3
omega = 3/8
u = -(m1/(abs(x-x1))**3)*(x-x1)-(m2/(abs(x-x2))**3)*(x-x2)+ x*omega
v = -(m1/(abs(y))**3)*(y)-(m2/(abs(y))**3)*(y)+ y*omega
fig, ax = plt.subplots()
ax.quiver(x,y,u,v)
plt.show()
A nice way, I find, to have a look at your data is to normalise the vector field and colour it by intensity. You can always mask glyphs for which the intensity is too low by using a Numpy MaskedArray. Have a look below.
import matplotlib.colors as cl
import matplotlib.pyplot as plt
import matplotlib.ticker as tck
import numpy as np
x, y = np.meshgrid(np.linspace(-2, 2, 41), np.linspace(-2, 2, 41))
m1, m2, x1, x2, omega = (1, 2, 4 / 3, 2 / 3, 3 / 8)
u = -(m1 / abs(x - x1) ** 3 * (x - x1) - m2 / abs(x - x2) ** 3 * (x - x2)
+ x * omega)
v = y * (omega - (m1 + m2) / abs(y) ** 3)
fig, (ax, bx) = plt.subplots(ncols=2, figsize=(20, 10))
ax.quiver(x, y, u, v, antialiased=True, scale=1e4, width=6e-3, headwidth=3,
headlength=4, headaxislength=3.5, pivot='tail',
edgecolors='xkcd:white', linewidths=1)
ax.set_aspect('equal')
w = np.sqrt(u ** 2 + v ** 2)
quiv = bx.quiver(x, y, u / w, v / w, w, antialiased=True, scale=3e1,
width=6e-3, headwidth=3, headlength=4, headaxislength=3.5,
pivot='tail', edgecolors='xkcd:white', linewidths=1,
norm=cl.LogNorm(vmin=1e-1, vmax=1e3))
bx.set_aspect('equal')
fig.colorbar(quiv, cax=fig.add_axes([0.93, 0.1, 0.02, 0.8]),
extend='both', ticks=tck.LogLocator(),
format=tck.LogFormatterSciNotation())
Some of the y values are close to 0 so that you get crazily large v values. I would check the equation because the plot is actually correct (the arrows are infinitely large when y ~= 0).
I am working on a piece of code which models the expansion of the universe, in particular I am integrating (using scipy odeint) the Friedmann equation to get a plot of the scale factor against time for different curvature. My code is:
import numpy as np
import matplotlib.pyplot as plt
import scipy as sp
from scipy.integrate import odeint
t_0 = 0.0004
a_0 = 0.001
omega_m = 1
omega_r = 0
omega_lambda = 0
omega_k = 1 - omega_lambda - omega_m - omega_r
H_0 = 1./13.799
def Friedmann(a, t):
dadt = H_0 * (((omega_m) * a**(-1)) + ((omega_r) * a**(-2)) + ((omega_lambda) * a**2) + (omega_k))**(1./2.)
return dadt
plt.rc('text', usetex=True)
plt.rc('font', family='serif')
fig, ax = plt.subplots(nrows=1,ncols=1)
for omega_k in np.linspace(-1, 1, 3):
t = np.linspace(t_0,50,200)
a = odeint(Friedmann, a_0, t)
a = np.array(a).flatten()
ax.plot(t,a)
line1, = plt.plot(t, a, 'b')
plt.xlabel('Time/Gyr')
plt.ylabel('Scale factor a')
plt.grid(True)
plt.axis([0,50,0,5])
plt.show()
This is the plot I get. I am trying to get a plot where the bottom (light blue) line loops back down and meets the x-axis at t ~ 43 Gyr but I can't seem to get this (maybe something to do with the integration).
Any help is much appreciated.
Ok, so Im not sure if this is even possible. I am trying to plot a graph in python, using matplotlib, that has a natural log function of both x and y.
First, I looked for posts containing instructions on how-to plot using a natural log. I found part of an answer here and the other part here.
The problem is, I am trying to plot two lines onto one graph.
The equations are:
1) 0.91 - 0.42 * P = Q
2) 6.999 - .7903 * ln (P) = ln (Q)
Is it possible to overlay these two lines onto one graph given the scale issue? How would I do it?
I tried the following:
from pylab import *
import matplotlib.pyplot as plt
import matplotlib
get_ipython().magic('matplotlib inline')
import numpy as np
import pandas as pd
P = np.linspace(0, 1, 11)
P
matplotlib.rcParams['xtick.major.pad'] = 5
matplotlib.rcParams['ytick.major.pad'] = 5
fig, ax = plt.subplots(figsize = (12,6))
axes = plt.gca()
axes.set_ylim([0, 16])
ax.plot(P, 0.91 - 0.42 * P, color = "BLUE", lw = 3, label = 'C1')
x = P ** np.e
y = 6.999 - .7903 * x
y1 = y ** np.e
ax.loglog(x, y, basex = np.e, basey = np.e)
ax.legend()
ax.set_title("Cluster 1 Pricing")
ax.xaxis.labelpad = 5
ax.yaxis.labelpad = 5
ax.set_xlabel("Norm P")
ax.set_ylabel("Norm Q");
But this returns the error:
ValueError: posx and posy should be finite values
It seems you want to plot
q1 = lambda p: 0.91 - 0.42 * p
q2 = lambda p: np.exp(6.999 - .7903 * np.log(p))
This can be done by supplying an array P to those functions and using the plot functions you already have in the code. Mind that you should not attempt to plot 0 on a logrithmic scale.
import matplotlib.pyplot as plt
import numpy as np
P = np.linspace(0.01, 1, 11)
fig, ax = plt.subplots(figsize = (12,6))
q1 = lambda p: 0.91 - 0.42 * p
q2 = lambda p: np.exp(6.999 - .7903 * np.log(p))
ax.plot(P, q1(P), color = "BLUE", lw = 3, label = 'Q1')
ax.loglog(P, q2(P), basex = np.e, basey = np.e,
color = "crimson", lw = 2, label = 'Q2')
ax.legend()
ax.set_title("Cluster 1 Pricing")
ax.set_xlabel("Norm P")
ax.set_ylabel("Norm Q")
plt.show()
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)