tharvey
tharvey

Reputation: 57

Graphing Distributions in Discrete Time with pyplot

I have a bunch of distributions of chemical concentrations that correspond to discrete times. I would like to plot these distributions all on the same plot (a plots of plots) in a sort of way that is done in these pictures (the first picture comes from Doing Bayesian Data Analysis, Kruschke):enter image description here

Right now I have these distributions as parameters to scipy distribution objects and am able to graph them individually, like (where normal_param, comes from scipy.optimize.curve_fit on the normal cdf):

from matplotlib import pyplot as plt
import numpy

# values = [some float, some other float] which is a list of cdf sample concentrations 
values = [...,...] 

mean = numpy.mean(values)
std = numpy.std(values)

x1 = numpy.linspace(mean - (4*std), mean + (6*std), num=200)

plt.plot(x1, stats.norm.pdf(x1, scale=normal_param[1], loc=normal_param[0]), 
linewidth=2.0, color='g')

I am new to matplotlib, and am not completely sure where to even start with the process of adding each of these individual plots to make the multiple distribution plot.

How can I make a plot that looks like these in matplotlib?

Upvotes: 0

Views: 395

Answers (1)

jdamp
jdamp

Reputation: 1460

This is a quick solution to achieve something similar to what you desire. It is based on two tricks:

  1. Use ax.plot(y,x) instead of ax.plot(x,y) to get the orientation of the gaussians similar to your example
  2. Plot all your gaussians on the same axis, but each time an increased offset is added to avoid overlapping.

This is implemented in the following code:

from scipy import stats
import matplotlib.pyplot as plt
import numpy as np


# Dummy values and dummy gaussian for plotting
gauss = lambda x, mu, sig, offset: offset-stats.norm.pdf(x, loc=mu, scale=sig)
means = [0, 1.5, 2.4, 2.8, 3.2]
scales = [1, 0.8, 0.6, 0.8, 0.7]
timesteps = list(range(len(means)))

# The actual plotting
fig, ax = plt.subplots(figsize=(6,4))
for mean, scale, ts in zip(means, scales, timesteps):
    y_plot = np.linspace(mean-2*scale, mean+2*scale, 500)    
    ax.plot(gauss(y_plot, mean, scale, ts), y_plot, color='b')
    ax.plot(gauss(mean, mean, scale, ts), mean, 'o', color='b')
ax.set_xticks(timesteps)
ax.set_xlabel('timesteps')
ax.set_ylabel('Concentration')
ax.set_ylim([-3,6])
plt.show()

which results in the following plot:

enter image description here

Upvotes: 3

Related Questions