A Tutorial on Generating & Plotting 3D Gaussian Distributions with (Python/Numpy/Tensorflow/Pytorch) & (Matplotlib/Plotly).

Aly Shmahell
Towards Data Science
4 min readAug 25, 2019

--

Problem Statement:

Whenever plotting Gaussian Distributions is mentioned, it is usually in regard to the Univariate Normal, and that is basically a 2D Gaussian Distribution method that samples from a range array over the X-axis, then applies the Gaussian function to it, and produces the Y-axis coordinates for the plot.

In the case of a 3D Gaussian Distribution however, the sampling happens over both the X-axis and the Y-axis, and the coordinates are projected over the Z-axis. This case is rarely mentioned in tutorials, although it is very useful in many situations.

Solution Outline:

To sample over two axes: X and Y, you need to sample all of the Y-Axis for each sample over the X-axis.

The complete sampling over both axes will produce ranges, one over the X-axis and one over the Y-axis.

When done, you need to generate a domain over the Z-axis, this can be done by calculating the distances of the (X, Y) samples.

The Z domain can then be run through the Gaussian function to produce the Gaussian range over the Z-axis.

A 3D plotter then can be constructed to utilize all three ranges to produce a 3D surface.

Mathematical Breakdown:

  • The X range needs to be a 2D matrix of size:
  • The X intermediate range is a line space (1D range array) from “-domain” to “+domain” with each step the size of “variance”, the number of elements in this 1D array should be:
  • The X range is the result of stacking copies of the X intermediate range, the number of copies should be:
  • The Y range is the transpose of the X range matrix.
  • The Z domain is the distance between X and Y:
  • The Z range is the result of applying the Gaussian function on the distance matrix (the Z domain):

Code Implementations:

Bivariate Normal (Gaussian) Distribution Generator made with Pure Python

  • The X range is constructed without a numpy function.
  • The Y range is the transpose of the X range matrix (ndarray).
  • The final resulting X-range, Y-range, and Z-range are encapsulated with a numpy array for compatibility with the plotters.

Bivariate Normal (Gaussian) Distribution Generator made with Numpy

  • The X intermediate range is constructed with numpy using the “arange” function.
  • The Y intermediate range is constructed with numpy using the “arange” function.
  • The X, Y ranges are constructed with the “meshgrid” function from numpy.

Bivariate Normal (Gaussian) Distribution Generator made with Tensorflow

  • The X intermediate range is constructed with tensorflow using the “range” function.
  • The Y intermediate range is constructed with tensorflow using the “range” function.
  • The X, Y ranges are constructed with the “meshgrid” function from tensorflow.

Bivariate Normal (Gaussian) Distribution Generator made with PyTorch

  • The X intermediate range is constructed with torch using the “arange” function.
  • The Y intermediate range is constructed with torch using the “arange” function.
  • The X, Y ranges are constructed with the “meshgrid” function from torch.

Bivariate Normal Plotter with Matplotlib

Bivariate Normal Plotter with Plotly (Version 4.0.0)

Plotting the Python generated bivariate normal distribution with Matplotlib

plt_plot_bivariate_normal_pdf(*py_bivariate_normal_pdf(6, 4, .25))

Plotting the Numpy generated bivariate normal distribution with Matplotlib

plt_plot_bivariate_normal_pdf(*np_bivariate_normal_pdf(6, 4, .25))

Plotting the Tensorflow generated bivariate normal distribution with Matplotlib

plt_plot_bivariate_normal_pdf(*tf_bivariate_normal_pdf(6, 4, .25))

Plotting the PyTorch generated bivariate normal distribution with Matplotlib

plt_plot_bivariate_normal_pdf(*torch_bivariate_normal_pdf(6, 4, .25))

Plotting the Python generated bivariate normal distribution with Plotly

plotly_plot_bivariate_normal_pdf(*py_bivariate_normal_pdf(6, 4, .25))

Plotting the Numpy generated bivariate normal distribution with Plotly

plotly_plot_bivariate_normal_pdf(*np_bivariate_normal_pdf(6, 4, .25))

Plotting the Tensorflow generated bivariate normal distribution with Plotly

plotly_plot_bivariate_normal_pdf(*tf_bivariate_normal_pdf(6, 4, .25))

Plotting the PyTorch generated bivariate normal distribution with Plotly

plotly_plot_bivariate_normal_pdf(*torch_bivariate_normal_pdf(6, 4, .25))

Note to the reader:

Please feel free to provide feedback, the reason behind these tutorials afterall is to exchange knowledge, and correct course in case of errors.

--

--

A Computer Scientist with a background in Computer Engineering, a tech enthusiast, and an open-source advocate. https://buymeacoff.ee/AlyShmahell