I wanted to plot y=(x+2)(x−1)(x−2) for x going from −3 to 3 using a dashed red line. When I wrote the following code, nothing shows up.
import numpy as np
import matplotlib.pyplot as plt
def graph(formula, x_range):
x = np.array(x_range)
y = eval(formula)
plt.plot(x, y)
plt.show()
graph('((x-3) * (x-2))', range(-3,3))
Make sure graph(..) call is outside the graph function definition (IOW, indent correctly):
import numpy as np
import matplotlib.pyplot as plt
def graph(formula, x_range):
x = np.array(x_range)
y = eval(formula)
plt.plot(x, y, 'r--') # `r--` for dashed red line
plt.show()
graph('((x-3) * (x-2))', range(-3,3)) # <----
UPDATE
It's not a good idea to use eval. Instead you can pass a function in this case.
def graph(formula, x_range):
x = np.array(x_range)
y = formula(x) # <-----
plt.plot(x, y, 'r--')
plt.show()
graph(lambda x: (x-3) * (x-2), range(-3,3)) # <---
Related
I draw an exponential chart and now I want to move the peak freely along the X axis.
The center should be like a bell, and the right side like a my current chart but totaly reversed.
How can I do that?
import matplotlib
import math
import numpy as np
matplotlib.use('Agg')
import matplotlib.pyplot as plt
arr_name=[]
arr_value=[]
k=-0.01
for l in range(0,100):
x=pow(k,2)*np.exp(-k*1.8);
if (l%10)==0:
arr_name.append(l/10)
else:
arr_name.append("")
arr_value.append(x)
k=k+0.05
print x
y_pos = np.arange(len(arr_name))
plt.figure(figsize=(8,4))
plt.rcParams.update({'font.size': 8})
plt.subplot(1,1,1)
plt.plot(y_pos, arr_value, '-r')
plt.xticks(y_pos, arr_name)
plt.savefig('/var/www/html/bar/img/test_chart.png')
update:
possible solution to draw peak at the center of the chart:
for l in range(0,100):
x=pow(k,5)*np.exp(-k*1.96);
if (l%10)==0:
arr_name.append(l/10)
else:
arr_name.append("")
arr_value.append(x)
if l>50:
k=k-0.05
else:
k=k+0.05
print x
adding reversibility:
arr_value.reverse()
You can plot this much easier without a four loop. Varying the coefficient inside the exponential moves the value and location of the peak.
import matplotlib.pyplot as plt
import numpy as np
def f(x, s):
x**2 * np.exp(-s*x)
x = np.linspace(0, 10, 100)
y1 = f(x, 1.8)
y2 = f(x, 0.8)
plt.plot(x, y1, label='s=1.8')
plt.plot(x, y2, label='s=0.8')
plt.legend()
plt.show()
This is the code I have so far, I'm trying to set the y limit to be [0,4] and the x limit to be [-2,3]. I can take care of the plot titles myself but I can't figure out how to get these two functions on the same graph.
import math as m
from matplotlib import pylab as plt
import numpy as np
def fermi_dirac(x):
fermi_result = (1/(np.exp(x)+1))
return fermi_result
def bose_einstein(x):
bose_result = (1/(np.exp(x)-1))
return bose_result
Here is a template to get you going
import math as m
import matplotlib.pyplot as plt
import numpy as np
def fermi_dirac(x):
fermi_result = (1./(np.exp(x)+1))
return fermi_result
def bose_einstein(x):
bose_result = (1/(np.exp(x)-1))
return bose_result
x = np.linspace( -2,3, 100)
fd = fermi_dirac(x)
be = bose_einstein(x)
plt.figure()
plt.plot(x, fd, label='fermi dirac')
plt.plot(x, be, label ='bose einstein')
plt.legend(loc='best')
plt.show()
Here's what I did and it works fine with the exception of a divide by zero error for certain values (I'm assuming graphical asymptotes):
import matplotlib.pyplot as plt
import numpy as np
def fermi_dirac(x):
fermi_result = (1/(np.exp(x)+1))
return fermi_result
def bose_einstein(x):
bose_result = (1/(np.exp(x)-1))
return bose_result
f = plt.figure()
x_vals = range(-2,3)
plt.plot(x_vals, fermi_dirac(x_vals))
plt.plot(x_vals, bose_einstein(x_vals))
plt.show()
Here's the documentation for pyplot when you need more references: https://matplotlib.org/api/_as_gen/matplotlib.pyplot.html
To get those functions on the same plot, just use plt.plot(...) two times.
Reference: How to plot multiple functions on the same figure, in Matplotlib?
import math as m
from matplotlib import pylab as plt
import numpy as np
def fermi_dirac(x):
fermi_result = (1/(np.exp(x)+1))
return fermi_result
def bose_einstein(x):
bose_result = (1/(np.exp(x)-1))
return bose_result
x = np.linspace(-2, 3, 100)
y1 = fermi_dirac(x)
y2 = bose_einstein(x)
plt.plot(x, y1, 'r')
plt.plot(x, y2, 'b')
plt.ylim(0, 4)
plt.show()
Output:
Very simple, you just have to define an array of input values (that you can call x). Here's an example with 1000 such values, input as a line plot using both formulas and the axis ranges you provided:
x = np.linspace(-2, 3, 1000)
plt.xlim([-2, 3])
plt.ylim([0,4])
plt.plot(x, fermi_dirac(x), '-', x, bose_einstein(x), '--')
plt.show()
I am trying to plot a graph using matplotlib.pyplot.
import matplotlib.pyplot as plt
import numpy as np
x = [i for i in range (1,201)]
y = np.loadtxt('final_fscore.txt', dtype=np.float128)
plt.plot(x, y, lw=2)
plt.show()
It looks something like this:
I want to mark the first value of x where y has reached the highest ( which is already known, say for x= 23, y= y[23]), like this figure shown below:
I have been searching this for some time now, with little success. I have tried adding a straight line for now, which is not behaving the desired way:
import matplotlib.pyplot as plt
import numpy as np
x = [i for i in range (1,201)]
y = np.loadtxt('final_fscore.txt', dtype=np.float128)
plt.plot(x, y, lw=2)
plt.plot([23,y[23]], [23,0])
plt.show()
Resulting graph:
Note: I want to make the figure like in the second graph.
It's not clear what y[23] would do here. You would need to find out the maximum value and the index at which this occurs (np.argmax). You may then use this to plot a 3 point line with those coordinates.
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(9)
x = np.arange(200)
y = np.cumsum(np.random.randn(200))
plt.plot(x, y, lw=2)
amax = np.argmax(y)
xlim,ylim = plt.xlim(), plt.ylim()
plt.plot([x[amax], x[amax], xlim[0]], [xlim[0], y[amax], y[amax]],
linestyle="--")
plt.xlim(xlim)
plt.ylim(ylim)
plt.show()
creating a log Axes3D object is an issue (see here)
a workaround is
import matplotlib.ticker as mticker
ax.plot_surface(x, y, np.log10(z))
def log_tick_formatter(val, pos=None):
return "{:.2e}".format(10**val)
ax.zaxis.set_major_formatter(mticker.FuncFormatter(log_tick_formatter))
this produces zticks of the form 1.0e-5.
How should I modify it to have ticks of the (LaTeX)
form 10^{-5} (as in standard logplots)?
Here is a minimal example to play with. Many thanks in advance!
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.ticker as mticker
fig = plt.figure()
ax = fig.gca(projection="3d")
x = np.arange(5+1)
y = np.arange(6+1)
X, Y = np.meshgrid(x, y)
Z = np.zeros(X.shape)
for ii in x:
for jj in y:
Z[jj, ii] = -min(ii, jj)
ax.plot_wireframe(X, Y, Z)
ax.view_init(elev=10, azim=-45)
def log_tick_formatter(val, pos=None):
return "{:.0e}".format(10**val)
ax.zaxis.set_major_formatter(mticker.FuncFormatter(log_tick_formatter))
plt.gca().invert_yaxis()
plt.show()
plt.close()
You can use the following format:
def log_tick_formatter(val, pos=None):
return r"$10^{{{:.0f}}}$".format(val)
but be aware that this - just like your solution - only works, if ticks are accidentally placed at whole numbers.
When I plot something with contourf, I see at the bottom of the plot window the current x and y values under the mouse cursor.
Is there a way to see also the z value?
Here an example contourf:
import matplotlib.pyplot as plt
import numpy as hp
plt.contourf(np.arange(16).reshape(-1,4))
The text that shows the position of the cursor is generated by ax.format_coord. You can override the method to also display a z-value. For instance,
import matplotlib.pyplot as plt
import numpy as np
import scipy.interpolate as si
data = np.arange(16).reshape(-1, 4)
X, Y = np.mgrid[:data.shape[0], :data.shape[1]]
cs = plt.contourf(X, Y, data)
func = si.interp2d(X, Y, data)
def fmt(x, y):
z = np.take(func(x, y), 0)
return 'x={x:.5f} y={y:.5f} z={z:.5f}'.format(x=x, y=y, z=z)
plt.gca().format_coord = fmt
plt.show()
The documentation example shows how you can insert z-value labels into your plot
Script: http://matplotlib.sourceforge.net/mpl_examples/pylab_examples/contour_demo.py
Basically, it's
plt.figure()
CS = plt.contour(X, Y, Z)
plt.clabel(CS, inline=1, fontsize=10)
plt.title('Simplest default with labels')
Just a variant of wilywampa's answer. If you already have a pre-computed grid of interpolated contour values because your data is sparse or if you have a huge data matrix, this might be suitable for you.
import matplotlib.pyplot as plt
import numpy as np
resolution = 100
Z = np.arange(resolution**2).reshape(-1, resolution)
X, Y = np.mgrid[:Z.shape[0], :Z.shape[1]]
cs = plt.contourf(X, Y, Z)
Xflat, Yflat, Zflat = X.flatten(), Y.flatten(), Z.flatten()
def fmt(x, y):
# get closest point with known data
dist = np.linalg.norm(np.vstack([Xflat - x, Yflat - y]), axis=0)
idx = np.argmin(dist)
z = Zflat[idx]
return 'x={x:.5f} y={y:.5f} z={z:.5f}'.format(x=x, y=y, z=z)
plt.colorbar()
plt.gca().format_coord = fmt
plt.show()
Ex: