plots in python¶
In [1]:
import matplotlib.pyplot as plt
import numpy as np
A simple plot:
In [2]:
x = np.linspace(0,2*np.pi,361)
fx = np.sin(x)
plt.plot(x,fx)
plt.show()
In [3]:
rng = np.random.default_rng() # make a RNG
u = rng.random(50) * 2 * np.pi
v = np.sin(u) + rng.normal(0,1/4,50)
plt.plot(x,fx,label= "true underlying function")
plt.plot(u,v,'o',label = "noisy observations")
plt.xlabel('x')
plt.legend()
plt.show()
Another way to set up a figure and a set of axes and build a plot and then show it.
In [4]:
fig, ax = plt.subplots( figsize = (10,4))
ax.plot(x,fx, label = "True function")
ax.plot(u,v,'o', label = "observations")
ax.set_title("A cool plot")
ax.legend()
ax2 = ax.twinx()
ax2.hist(u,color= (0.545,0,0,.2))
ax2.set_ylabel('Frequency of observations')
plt.show()
In [5]:
fig, axs = plt.subplot_mosaic([['A','B'],['Bottom','Bottom']], figsize=(10,8) )
axs['A'].plot(u,v,'o')
axs['B'].plot(x,fx)
axs['Bottom'].hist(u)
fig.suptitle('An example of subplot mosaic', fontsize = 18, y = .95)
plt.show()
Defining functions in Python¶
In [6]:
def f(x): return( x * np.sin(x))
f(1)
Out[6]:
0.8414709848078965
A function with more than one line:
Say we want to get the hypotenuse from two sides of a right triangle.
In [7]:
def hyp(a,b):
csq = a**2 + b**2
c = np.sqrt(csq)
return c
print(hyp(3,4))
print(hyp(5,10))
5.0 11.180339887498949
What if we want a function to return more than one output??
Example: A function which gives Euclidean coordinates from polar.
In [8]:
def eucl(r,th):
x = r * np.cos(th)
y = r * np.sin(th)
return x, y
print(eucl(r=1,th=np.pi/2))
print(eucl(r=1,th=np.pi/3))
(6.123233995736766e-17, 1.0) (0.5000000000000001, 0.8660254037844386)
A function which takes some values by default:
In [9]:
def logistic(x,a=0,b=1):
l = a + b * x
val = np.exp(l) / (1 + np.exp(l))
return val
In [10]:
x = np.linspace(-4,4,201)
fx1 = logistic(x)
fx2 = logistic(x,a = 2,b=2)
plt.rcParams['text.usetex'] # this allows you to use LaTex code in your plot labels
fig, ax = plt.subplots(figsize = (10,5))
ax.plot(x,fx1, label = '$a = 0$, $b = 1$')
ax.plot(x,fx2, label = '$a = 2$, $b = 2$')
ax.text(-3, .6, "$f(x) = \\frac{e^{a + b x}}{1 + e^{a + bx} }$")
ax.legend()
plt.show()
Conditional programming¶
Make a function which rolls two dice and prints different phrases depending on the outcome.
In [11]:
np.random.choice(np.arange(1,7),1) # roll a six-sided die
Out[11]:
array([3])
In [12]:
def rolldice():
# roll two six-sided dice
r1 = np.random.choice(np.arange(1,7),1)
r2 = np.random.choice(np.arange(1,7),1)
print("You rolled a " + str(r1) + " and a " + str(r2) + ".")
if(r1 == r2):
print("Doubles!!!!!")
elif( (r1 + r2) > 10):
print("No doubles, but pretty nice.")
else:
print("Not bad.")
In [13]:
rolldice()
You rolled a [3] and a [5]. Not bad.
Can take advantage of coercion of booleans to numbers when we do conditional programming:
In [14]:
def softthresh(x,lam):
return (x < -lam)*(x + lam) + (x > lam)*(x - lam)
A cool 3d plot¶
In [15]:
def bivn(x,y,rho=0):
r = 1 - rho**2
z = x**2 + y**2 - 2*rho*x*y
f = 1/(2 * np.pi) * 1/np.sqrt(r) * np.exp( - z / (2 * r))
return f
bivn(1,1/2,-1/4)
Out[15]:
0.07385823208730814
In [16]:
gs = 101 # this is the "grid size"
grid = np.linspace(-3,3,gs)
X, Y = np.meshgrid(grid,grid)
F = bivn(X,Y,rho=1/2)
fig = plt.figure(figsize = (8,8))
ax = fig.add_subplot(projection='3d')
ax.plot_surface(X,Y,F, cmap = plt.cm.YlGnBu_r)
plt.show()