I'm trying to plot two functions on one plot - python

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()

Related

Marking y value using dotted line in matplotlib.pyplot

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()

nicer ticks for logarithmic Axes3D

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.

Python: Creating a plot inside of a for loop with two different variables

I am trying to plot a function with two parameters. In this case I'd like the function to plot with respect to "yy" in order for it to be in polar coordinates. When I run the program I get 10 figures rather than 1 single plot. Is there a reason this happens? Also, I'm not getting a plot at all.
import scipy.optimize as opt
import matplotlib.pyplot as plt
import pylab as pyl
freq = 9.75e9
lmda = 299792458./freq
k = 2*np.pi/lmda
h1 = 0.25*lmda
def theta(x,y):
th = np.arctan(y,x)
return th
def F(x,y):
f=2*np.abs(np.sin(k*h1*theta(x,y)))
return f
def gain(x,y):
return 10*np.log10(F(x,y)**2)
xx = np.arange(0,2000,200)
yy = np.linspace(0,np.pi/2,1000)
for tval in xx:
plt.rcParams['text.latex.preamble']=[r'\usepackage{amsmath}']
plt.rc('text',usetex=True)
font = {'family':'serif','size':20}
plt.rc('font',**font)
fig, ax=plt.subplots(subplot_kw=dict(projection='polar'))
ticks = np.arange(0,360,45)
ax.set_ylim(-40,10)
ax.set_yticks([-40,-30,-20,-10,0])
ax.set_yticklabels(['','30','20','10',''],verticalalignment='center',horizontalalignment='center')
ax.set_thetagrids(ticks, frac=1.2)
ax.set_xlim(0, np.pi/2)
ax.set_theta_zero_location('N') # changes the orienation of theta
ax.plot(yy,gain(yy,tval)) #dipole elevation plane pattern
plt.tight_layout()
plt.show()
You need a little restructure:
import scipy.optimize as opt
import matplotlib.pyplot as plt
import pylab as pyl
import numpy as np
freq = 9.75e9
lmda = 299792458./freq
k = 2*np.pi/lmda
h1 = 0.25*lmda
def theta(x,y):
th = np.arctan(y,x)
return th
def F(x,y):
f=2*np.abs(np.sin(k*h1*theta(x,y)))
return f
def gain(x,y):
return 10*np.log10(F(x,y)**2)
xx = np.arange(0,2000,200)
yy = np.linspace(0,np.pi/2,1000)
plt.rcParams['text.latex.preamble']=[r'\usepackage{amsmath}']
plt.rc('text',usetex=True)
font = {'family':'serif','size':20}
plt.rc('font',**font)
fig, ax=plt.subplots(subplot_kw=dict(projection='polar'))
ticks = np.arange(0,360,45)
ax.set_ylim(-40,10)
ax.set_yticks([-40,-30,-20,-10,0])
ax.set_yticklabels(['','30','20','10',''],verticalalignment='center',horizontalalignment='center')
ax.set_thetagrids(ticks, frac=1.2)
ax.set_xlim(0, np.pi/2)
ax.set_theta_zero_location('N') # changes the orienation of theta
for tval in xx:
ax.plot(yy,gain(yy,tval)) #dipole elevation plane pattern
plt.tight_layout()
plt.show()
You also should handle the division by zero error.

extracting data from sns.kdeplot python

Is it possible to extract the data from a sns.kdeplot() before plotting?
ie. without using the function
y.get_lines()[0].get_data() post plotting
This can be done by extracting the line data from the matplotlib Axes object:
import numpy as np
from seaborn import kdeplot
my_data = np.random.randn(1000)
my_kde = kdeplot(my_data)
line = my_kde.lines[0]
x, y = line.get_data()
fig, ax = plt.subplots()
ax.plot(x[x>0], y[x>0])
alternatively the statsmodels way:
import statsmodels.api as sm
dens = sm.nonparametric.KDEUnivariate(np.random.randn(1000))
dens.fit()
x =np.linspace(0,1,100) #restrict range to (0,1)
y = dens.evaluate(x)
plt.plot(x,y)
Based on statsmodels's documentation:
import numpy as np
import seaborn as sns
import statsmodels.api as sm
import matplotlib.pyplot as plt
# generate bimodal disrtibution
X1 = np.random.normal(100, 10, 250)
X2 = np.random.normal(10, 20, 250)
X = np.concatenate([X1, X2])
# get density from seaborn
x, y = sns.kdeplot(X).lines[0].get_data()
# get density from statsmodel
kde = sm.nonparametric.KDEUnivariate(X).fit()
xx, yy = (kde.support, kde.density)
# compare outputs
plt.plot(x, y, label='from sns')
plt.plot(xx, yy, label='from statsmodels')
plt.legend()

Graphs in python using matplotlib

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)) # <---

Categories

Resources