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()
Related
I'm trying to find the FWHM of a curve I've generated. This is the code for the curve and a picture of what it looks like.
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
from scipy.signal import peak_widths, find_peaks
k = np.load('/data/Var/test.npy')
x = np.load('/data/Var/sigrng.npy')
peakk = find_peaks(k)
kfwhm = peak_widths(k, peakk[0], rel_height=0.5)
plt.plot(x, k, ls='--', color='red')
plt.show()
Which produces this curve:
However, when I print out the output from what is supposed to be the FWHM and plot it on the curve it's not evaluating on the actual curve and is giving values much larger than what I expect.
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
from scipy.signal import peak_widths, find_peaks
k = np.load('/data/Var/test.npy')
x = np.load('/data/Var/sigrng.npy')
peakk = find_peaks(k)
kfwhm = peak_widths(k, peakk[0], rel_height=0.5)
plt.plot(x, k, ls='--', color='red')
plt.hlines(*kfwhm[1:], color="red")
plt.show()
Can anyone see anything I'm doing wrong that could cause this? When checking where the peak in the curve is manually the find_peaks function is working correctly.
I worked out the problem. It is due to the fact that when it calculates the FWHM it does not take into account the x values that you plot the curve against. Since my plots are supposed to go between 0 and 1 I simply divide the values by the size of the array on the y axis (here the array k) and it fixes the issue. Code below:
peakk, _ = find_peaks(k)
kfwhm = peak_widths(k, peakk, rel_height=0.5)
kfwhm = np.asarray(kfwhm)
plt.plot(x_k, k, ls='--', color='red')
plt.hlines(0.5, *(kfwhm[2:]/k.size), color="blue")
plt.show()
Giving:
and a FWMH of:
print(kfwhm[0]/k.size)
Out[384]: array([0.02415405])
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'm using Matplotlib's function hist2d() and I want to unpack the output in order to further use it. Here's what I do: I simply load with numpy a 2-column file containing my data and use the following code
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
import numpy as np
traj = np.loadtxt('trajectory.txt')
x = traj[:,0]
y = traj[:,1]
M, xe, ye, img = plt.hist2d(x, y, bins = 80, norm = LogNorm())
plt.imshow(M)
plt.show()
The result I get is the following:
Instead, if I try to directly plot the hist2d results without unpacking them:
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
import numpy as np
traj = np.loadtxt('trajectory.txt')
x = traj[:,0]
y = traj[:,1]
plt.hist2d(x, y, bins = 80, norm = LogNorm())
plt.show()
I get the whole plot without the strange blue box. What am I doing wrong?
You can create a histogram plot directly with plt.hist2d. This calculates the histogram and plots it to the current axes. There is no need to show it yet another time using imshow.
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
import numpy as np; np.random.seed(9)
x = np.random.rayleigh(size=9900)
y = np.random.rayleigh(size=9900)
M, xe, ye, img = plt.hist2d(x, y, bins = 80, norm = LogNorm())
plt.show()
Or, you may first calculate the histogram and afterwards plot the result as an image to the current axes. Note that the histogram produced by numpy is transposed, see Matplotlib 2D histogram seems transposed, making it necessary to call imshow(M.T). Also note that in order to obtain the correct axes labeling, you need to set the imshow's extent to the extremal values of the xe and ye edge arrays.
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
import numpy as np; np.random.seed(9)
x = np.random.rayleigh(size=9900)
y = np.random.rayleigh(size=9900)
M, xe, ye = np.histogram2d(x, y, bins = 80)
extent = [xe[0], xe[-1], ye[0], ye[-1]]
plt.imshow(M.T, extent=extent, norm = LogNorm(), origin="lower")
plt.show()
Is it possible, with Matplotlib, to print the values of each point on the graph?
For example, if I have:
x = numpy.range(0,10)
y = numpy.array([5,3,4,2,7,5,4,6,3,2])
pyplot.plot(x,y)
How can I display y values on the plot (e.g. print a 5 near the (0,5) point, print a 3 near the (1,3) point, etc.)?
You can use the annotate command to place text annotations at any x and y values you want. To place them exactly at the data points you could do this
import numpy
from matplotlib import pyplot
x = numpy.arange(10)
y = numpy.array([5,3,4,2,7,5,4,6,3,2])
fig = pyplot.figure()
ax = fig.add_subplot(111)
ax.set_ylim(0,10)
pyplot.plot(x,y)
for i,j in zip(x,y):
ax.annotate(str(j),xy=(i,j))
pyplot.show()
If you want the annotations offset a little, you could change the annotate line to something like
ax.annotate(str(j),xy=(i,j+0.5))
Use pyplot.text() (import matplotlib.pyplot as plt)
import matplotlib.pyplot as plt
x=[1,2,3]
y=[9,8,7]
plt.plot(x,y)
for a,b in zip(x, y):
plt.text(a, b, str(b))
plt.show()