import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.cm as cm
import matplotlib.gridspec as gridspec
from mpl_toolkits.axes_grid1 import make_axes_locatable
from scipy.stats import multivariate_normal
# interactive plotting (see first link of references below)
# %matplotlib widget
# standard plotting (non-interactive)
%matplotlib inline
# parameters of the bivariate Gaussian
# mu = [0.0, 0.0]
# sigma_x = 1
# sigma_y = 1
# rho = 0.
# mu = [0.0, 0.0]
# sigma_x = 1
# sigma_y = 0.5
# rho = 0.5
mu = [0.0, 0.0]
sigma_x = 1
sigma_y = 0.5
rho = -0.8
# covariance matrix
V = [[sigma_x**2, rho * sigma_x * sigma_y], [rho * sigma_x * sigma_y, sigma_y**2]]
# plot range
xmin = -3
xmax = 3
dx = 0.05
ymin = -3
ymax = 3
dy = 0.05
# 3d data
rv = multivariate_normal(mu, V)
x, y = np.mgrid[xmin:xmax:dx, ymin:ymax:dy]
pos = np.dstack((x, y))
z = rv.pdf(pos)
# color map
# cmap=cm.viridis, cmap=cm.YlGnBu
cmsel = cm.YlGnBu
fig = plt.figure(figsize=(5,5))
ax1 = fig.add_subplot(1,1,1,projection='3d')
ax1.set_xlabel(r'$x$', fontsize=16)
ax1.set_ylabel(r'$y$', fontsize=16)
ax1.view_init(30,-60)
ax1.plot_surface(x, y, z, rstride=2, cstride=2, linewidth=1, antialiased=True, cmap=cmsel);
def univariate_normal(x, mean, variance):
"""pdf of the univariate normal distribution."""
return ((1. / np.sqrt(2 * np.pi * variance)) *
np.exp(-(x - mean)**2 / (2 * variance)))
# Plot the conditional distributions
fig = plt.figure(figsize=(7, 7))
gs = gridspec.GridSpec(
2, 2, width_ratios=[2, 1], height_ratios=[2, 1])
# gs.update(wspace=0., hspace=0.)
plt.suptitle('Marginal distributions', y=0.93)
# Plot surface on top left
ax1 = plt.subplot(gs[0])
# Plot bivariate distribution
con = ax1.contourf(x, y, z, 10, cmap=cmsel)
ax1.set_xlabel('$x$', fontsize=16)
ax1.set_ylabel('$y$', fontsize=16)
ax1.yaxis.set_label_position('right')
ax1.axis([xmin, xmax, ymin, ymax])
# Plot y
ax2 = plt.subplot(gs[1])
yl = np.linspace(ymin, ymax, 100)
py = univariate_normal(yl, mu[1], sigma_y)
# Plot univariate distribution
ax2.plot(py, yl, 'b--', label=f'$f_y(y)$')
ax2.legend(loc=0)
ax2.set_xlabel('density', fontsize=16)
ax2.set_ylim(ymin, ymax)
# Plot x
ax3 = plt.subplot(gs[2])
xl = np.linspace(xmin, xmax, 100)
px = univariate_normal(xl, mu[0], sigma_x)
# Plot univariate distribution
ax3.plot(xl, px, 'b--', label=f'$f_x(x)$')
ax3.legend(loc=0)
ax3.set_ylabel('density', fontsize=16)
ax3.yaxis.set_label_position('right')
ax3.set_xlim(xmin, ymax)
# Clear axis 4 and plot colarbar in its place
ax4 = plt.subplot(gs[3])
ax4.set_visible(False)
divider = make_axes_locatable(ax4)
cax = divider.append_axes('left', size='20%', pad=0.05)
cbar = fig.colorbar(con, cax=cax)
cbar.ax.set_ylabel('density: $f(x, y)$', fontsize=16)
plt.show()