How to Plot a Normal Distribution with Matplotlib in Python

How to plot a normal distribution with Matplotlib in Python is an essential skill for data visualization and statistical analysis. This comprehensive guide will walk you through various methods and techniques to create normal distribution plots using Matplotlib, one of the most popular plotting libraries in Python. We’ll cover everything from basic concepts to advanced customization options, providing you with the knowledge and tools to effectively visualize normal distributions in your data science projects.

Understanding Normal Distribution and Its Importance

Before diving into the plotting techniques, it’s crucial to understand what a normal distribution is and why it’s important in data analysis. A normal distribution, also known as a Gaussian distribution, is a symmetric probability distribution that follows a bell-shaped curve. It’s characterized by its mean (μ) and standard deviation (σ), which determine the center and spread of the distribution, respectively.

Normal distributions are ubiquitous in nature and play a significant role in various fields, including statistics, physics, and social sciences. They’re often used to model real-world phenomena and are the foundation for many statistical tests and analyses.

Setting Up Your Python Environment

To plot a normal distribution with Matplotlib in Python, you’ll need to have the following libraries installed:

  1. Matplotlib
  2. NumPy
  3. SciPy (optional, but useful for generating normal distribution data)

You can install these libraries using pip:

pip install matplotlib numpy scipy

Once you have the necessary libraries installed, you’re ready to start plotting normal distributions with Matplotlib.

Basic Normal Distribution Plot

Let’s begin with a simple example of how to plot a normal distribution with Matplotlib in Python. We’ll use NumPy to generate the data and Matplotlib to create the plot.

import numpy as np
import matplotlib.pyplot as plt

# Generate data for the normal distribution
mu, sigma = 0, 1  # mean and standard deviation
x = np.linspace(mu - 3*sigma, mu + 3*sigma, 100)
y = 1/(sigma * np.sqrt(2 * np.pi)) * np.exp(-(x - mu)**2 / (2 * sigma**2))

# Create the plot
plt.figure(figsize=(10, 6))
plt.plot(x, y, label='Normal Distribution')
plt.title('How to Plot a Normal Distribution with Matplotlib in Python')
plt.xlabel('X-axis')
plt.ylabel('Probability Density')
plt.legend()
plt.grid(True)
plt.text(0, 0.1, 'how2matplotlib.com', fontsize=12, alpha=0.7)
plt.show()

Output:

How to Plot a Normal Distribution with Matplotlib in Python

In this example, we first generate the data for a standard normal distribution (mean = 0, standard deviation = 1) using NumPy’s linspace function to create evenly spaced x-values and the probability density function formula to calculate the corresponding y-values. Then, we use Matplotlib’s plot function to create the line plot, add labels, a title, and a legend, and finally display the plot using plt.show().

Histogram with Normal Distribution Overlay

Another common way to visualize a normal distribution is by creating a histogram of the data and overlaying a normal distribution curve. This method is particularly useful when working with real-world data that approximates a normal distribution.

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

# Generate random data
np.random.seed(42)
data = np.random.normal(loc=0, scale=1, size=1000)

# Create the histogram
plt.figure(figsize=(10, 6))
plt.hist(data, bins=30, density=True, alpha=0.7, color='skyblue', edgecolor='black')

# Generate points for the normal distribution curve
x = np.linspace(data.min(), data.max(), 100)
y = stats.norm.pdf(x, loc=data.mean(), scale=data.std())

# Plot the normal distribution curve
plt.plot(x, y, 'r-', lw=2, label='Normal Distribution')

plt.title('How to Plot a Normal Distribution with Matplotlib in Python: Histogram with Overlay')
plt.xlabel('Value')
plt.ylabel('Density')
plt.legend()
plt.text(0, 0.1, 'how2matplotlib.com', fontsize=12, alpha=0.7)
plt.show()

Output:

How to Plot a Normal Distribution with Matplotlib in Python

In this example, we generate random data from a normal distribution using NumPy’s random.normal function. We then create a histogram of the data using Matplotlib’s hist function with the density=True parameter to normalize the histogram. Finally, we overlay a normal distribution curve using SciPy’s stats.norm.pdf function to generate the curve points and Matplotlib’s plot function to draw the line.

Customizing Normal Distribution Plots

Matplotlib offers a wide range of customization options to enhance your normal distribution plots. Let’s explore some of these options:

Changing Colors and Styles

You can easily modify the colors and styles of your plots to make them more visually appealing or to match your project’s theme.

import numpy as np
import matplotlib.pyplot as plt

mu, sigma = 0, 1
x = np.linspace(mu - 3*sigma, mu + 3*sigma, 100)
y = 1/(sigma * np.sqrt(2 * np.pi)) * np.exp(-(x - mu)**2 / (2 * sigma**2))

plt.figure(figsize=(10, 6))
plt.plot(x, y, color='purple', linestyle='--', linewidth=2, label='Normal Distribution')
plt.fill_between(x, y, alpha=0.3, color='lavender')
plt.title('How to Plot a Normal Distribution with Matplotlib in Python: Custom Colors')
plt.xlabel('X-axis')
plt.ylabel('Probability Density')
plt.legend()
plt.text(0, 0.1, 'how2matplotlib.com', fontsize=12, alpha=0.7)
plt.show()

Output:

How to Plot a Normal Distribution with Matplotlib in Python

In this example, we’ve changed the line color to purple, used a dashed line style, increased the line width, and added a light fill color under the curve using plt.fill_between().

Adding Multiple Normal Distributions

You can plot multiple normal distributions on the same graph to compare different parameters or datasets.

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-5, 5, 100)
y1 = 1/(1 * np.sqrt(2 * np.pi)) * np.exp(-(x - 0)**2 / (2 * 1**2))
y2 = 1/(1.5 * np.sqrt(2 * np.pi)) * np.exp(-(x - 1)**2 / (2 * 1.5**2))

plt.figure(figsize=(10, 6))
plt.plot(x, y1, label='μ=0, σ=1')
plt.plot(x, y2, label='μ=1, σ=1.5')
plt.title('How to Plot a Normal Distribution with Matplotlib in Python: Multiple Distributions')
plt.xlabel('X-axis')
plt.ylabel('Probability Density')
plt.legend()
plt.grid(True, linestyle=':', alpha=0.7)
plt.text(0, 0.1, 'how2matplotlib.com', fontsize=12, alpha=0.7)
plt.show()

Output:

How to Plot a Normal Distribution with Matplotlib in Python

This example demonstrates how to plot two normal distributions with different means and standard deviations on the same graph, allowing for easy comparison.

Using Subplots

Subplots are useful when you want to display multiple related plots side by side or in a grid layout.

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-5, 5, 100)
y1 = 1/(1 * np.sqrt(2 * np.pi)) * np.exp(-(x - 0)**2 / (2 * 1**2))
y2 = 1/(2 * np.sqrt(2 * np.pi)) * np.exp(-(x - 0)**2 / (2 * 2**2))

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

ax1.plot(x, y1, label='σ=1')
ax1.set_title('Normal Distribution (μ=0, σ=1)')
ax1.set_xlabel('X-axis')
ax1.set_ylabel('Probability Density')
ax1.legend()
ax1.text(0, 0.1, 'how2matplotlib.com', fontsize=10, alpha=0.7)

ax2.plot(x, y2, label='σ=2')
ax2.set_title('Normal Distribution (μ=0, σ=2)')
ax2.set_xlabel('X-axis')
ax2.set_ylabel('Probability Density')
ax2.legend()
ax2.text(0, 0.05, 'how2matplotlib.com', fontsize=10, alpha=0.7)

plt.suptitle('How to Plot a Normal Distribution with Matplotlib in Python: Subplots')
plt.tight_layout()
plt.show()

Output:

How to Plot a Normal Distribution with Matplotlib in Python

This example creates two subplots side by side, each showing a normal distribution with different standard deviations.

Advanced Techniques for Normal Distribution Plots

Now that we’ve covered the basics, let’s explore some advanced techniques for plotting normal distributions with Matplotlib in Python.

3D Normal Distribution Plot

You can create a 3D surface plot of a bivariate normal distribution to visualize the relationship between two variables.

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def bivariate_normal(X, Y, sigmax=1.0, sigmay=1.0, mux=0.0, muy=0.0, sigmaxy=0.0):
    Xmu = X-mux
    Ymu = Y-muy
    rho = sigmaxy/(sigmax*sigmay)
    z = Xmu**2/sigmax**2 + Ymu**2/sigmay**2 - 2*rho*Xmu*Ymu/(sigmax*sigmay)
    denom = 2*np.pi*sigmax*sigmay*np.sqrt(1-rho**2)
    return np.exp(-z/(2*(1-rho**2))) / denom

x = np.linspace(-3, 3, 100)
y = np.linspace(-3, 3, 100)
X, Y = np.meshgrid(x, y)
Z = bivariate_normal(X, Y, sigmax=1, sigmay=1, mux=0, muy=0, sigmaxy=0)

fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(X, Y, Z, cmap='viridis')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Probability Density')
ax.set_title('How to Plot a Normal Distribution with Matplotlib in Python: 3D Bivariate')
fig.colorbar(surf, shrink=0.5, aspect=5)
ax.text(0, 0, 0, 'how2matplotlib.com', fontsize=10, alpha=0.7)
plt.show()

Output:

How to Plot a Normal Distribution with Matplotlib in Python

This example creates a 3D surface plot of a bivariate normal distribution using Matplotlib’s 3D plotting capabilities.

Cumulative Distribution Function (CDF) Plot

The cumulative distribution function (CDF) is another important visualization of a normal distribution.

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

x = np.linspace(-4, 4, 100)
y = stats.norm.cdf(x)

plt.figure(figsize=(10, 6))
plt.plot(x, y, label='CDF')
plt.title('How to Plot a Normal Distribution with Matplotlib in Python: CDF')
plt.xlabel('X-axis')
plt.ylabel('Cumulative Probability')
plt.legend()
plt.grid(True, linestyle=':', alpha=0.7)
plt.text(0, 0.5, 'how2matplotlib.com', fontsize=12, alpha=0.7)
plt.show()

Output:

How to Plot a Normal Distribution with Matplotlib in Python

This example plots the cumulative distribution function of a standard normal distribution using SciPy’s stats.norm.cdf function.

Q-Q Plot

A Q-Q (Quantile-Quantile) plot is used to assess whether a dataset follows a normal distribution.

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

# Generate sample data
np.random.seed(42)
data = np.random.normal(loc=0, scale=1, size=1000)

# Create Q-Q plot
fig, ax = plt.subplots(figsize=(10, 6))
stats.probplot(data, dist="norm", plot=ax)
ax.set_title("How to Plot a Normal Distribution with Matplotlib in Python: Q-Q Plot")
ax.text(0, 0, 'how2matplotlib.com', fontsize=12, alpha=0.7)
plt.show()

Output:

How to Plot a Normal Distribution with Matplotlib in Python

This example creates a Q-Q plot using SciPy’s stats.probplot function, which compares the quantiles of the sample data to the quantiles of a theoretical normal distribution.

Visualizing Normal Distribution Properties

Understanding and visualizing the properties of a normal distribution is crucial for data analysis. Let’s explore some ways to visualize these properties using Matplotlib.

Standard Deviations and Percentiles

You can visualize the standard deviations and percentiles of a normal distribution to better understand its spread and central tendency.

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

x = np.linspace(-4, 4, 1000)
y = stats.norm.pdf(x)

plt.figure(figsize=(12, 6))
plt.plot(x, y, 'b-', label='Normal Distribution')
plt.fill_between(x, y, where=(x >= -1) & (x <= 1), color='red', alpha=0.3, label='68% (1σ)')
plt.fill_between(x, y, where=(x >= -2) & (x <= 2), color='green', alpha=0.2, label='95% (2σ)')
plt.fill_between(x, y, where=(x >= -3) & (x <= 3), color='blue', alpha=0.1, label='99.7% (3σ)')

plt.title('How to Plot a Normal Distribution with Matplotlib in Python: Standard Deviations')
plt.xlabel('X-axis (Standard Deviations)')
plt.ylabel('Probability Density')
plt.legend()
plt.grid(True, linestyle=':', alpha=0.7)
plt.text(0, 0.1, 'how2matplotlib.com', fontsize=12, alpha=0.7)
plt.show()

Output:

How to Plot a Normal Distribution with Matplotlib in Python

This example visualizes the 68-95-99.7 rule (also known as the empirical rule) by shading the areas within one, two, and three standard deviations of the mean.

Comparing Empirical Data to Normal Distribution

When working with real-world data, it's often useful to compare your empirical data to a theoretical normal distribution. Here are some techniques to do this using Matplotlib.

Overlay Empirical Data on Theoretical Normal Distribution

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

# Generate sample data
np.random.seed(42)
data = np.random.normal(loc=0, scale=1, size=1000)

# Calculate mean and standard deviation of the data
mu, std = np.mean(data), np.std(data)

# Create the plot
plt.figure(figsize=(10, 6))

# Plot histogram of empirical data
plt.hist(data, bins=30, density=True, alpha=0.7, color='skyblue', edgecolor='black', label='Empirical Data')

# Plot theoretical normal distribution
x = np.linspace(mu - 3*std, mu + 3*std, 100)
y = stats.norm.pdf(x, mu, std)
plt.plot(x, y, 'r-', lw=2, label='Theoretical Normal')

plt.title('How to Plot a Normal Distribution with Matplotlib in Python: Empirical vs Theoretical')
plt.xlabel('Value')
plt.ylabel('Density')
plt.legend()
plt.text(0, 0.1, 'how2matplotlib.com', fontsize=12, alpha=0.7)
plt.show()

Output:

How to Plot a Normal Distribution with Matplotlib in Python

This example generates sample data, creates a histogram of the empirical data, and overlays a theoretical normal distribution with the same mean and standard deviation as the sample data.

Probability Plot (P-P Plot)

A probability plot, or P-P plot, is another useful tool for comparing empirical data to a theoretical normal distribution.

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

# Generate sample data
np.random.seed(42)
data = np.random.normal(loc=0, scale=1, size=1000)

# Create P-P plot
fig, ax = plt.subplots(figsize=(10, 6))
stats.probplot(data, dist="norm", plot=ax)
ax.get_lines()[0].set_markerfacecolor('skyblue')
ax.get_lines()[0].set_markeredgecolor('blue')

ax.set_title("How to Plot a Normal Distribution with Matplotlib in Python: P-P Plot")
ax.set_xlabel("Theoretical Quantiles")
ax.set_ylabel("Sample Quantiles")
ax.text(0, 0, 'how2matplotlib.com', fontsize=12, alpha=0.7)
plt.show()

Output:

How to Plot a Normal Distribution with Matplotlib in Python

This example creates a P-P plot, which compares the cumulative distribution of the sample data to that of a theoretical normal distribution.

Advanced Customization Techniques

Matplotlib offers a wide range of advanced customization options to create publication-quality plots. Let's explore some of these techniques.

Custom Styling with Seaborn

Seaborn is a statistical data visualization library built on top of Matplotlib that provides a high-level interface for drawing attractive statistical graphics. You can use Seaborn to easily apply custom styles to your normal distribution plots.

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# Set Seaborn style
sns.set_style("whitegrid")
sns.set_palette("deep")

# Generate data
x = np.linspace(-4, 4, 100)
y = 1/(1 * np.sqrt(2 * np.pi)) * np.exp(-(x - 0)**2 / (2 * 1**2))

# Create the plot
plt.figure(figsize=(10, 6))
sns.lineplot(x=x, y=y, label='Normal Distribution')
sns.despine()

plt.title('How to Plot a Normal Distribution with Matplotlib and Seaborn in Python')
plt.xlabel('X-axis')
plt.ylabel('Probability Density')
plt.legend()
plt.text(0, 0.1, 'how2matplotlib.com', fontsize=12, alpha=0.7)
plt.show()

Output:

How to Plot a Normal Distribution with Matplotlib in Python

This example uses Seaborn to apply a custom style to the normal distribution plot, resulting in a more visually appealing graph.

Animation of Normal Distribution

You can create animated plots to visualize how changes in parameters affect the normal distribution.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

fig, ax = plt.subplots(figsize=(10, 6))
line, = ax.plot([], [], lw=2)
ax.set_xlim(-5, 5)
ax.set_ylim(0, 0.5)
ax.set_title('How to Plot a Normal Distribution with Matplotlib in Python: Animation')
ax.set_xlabel('X-axis')
ax.set_ylabel('Probability Density')
ax.text(0, 0.1, 'how2matplotlib.com', fontsize=12, alpha=0.7)

def init():
    line.set_data([], [])
    return line,

def animate(i):
    x = np.linspace(-5, 5, 100)
    y = 1/(i * np.sqrt(2 * np.pi)) * np.exp(-(x - 0)**2 / (2 * i**2))
    line.set_data(x, y)
    ax.set_title(f'Normal Distribution (σ = {i:.2f})')
    return line,

anim = FuncAnimation(fig, animate, init_func=init, frames=np.linspace(0.5, 2, 100), interval=50, blit=True)
plt.show()

Output:

How to Plot a Normal Distribution with Matplotlib in Python

This example creates an animation that shows how the normal distribution changes as the standard deviation increases.

Practical Applications of Normal Distribution Plots

Understanding how to plot a normal distribution with Matplotlib in Python is crucial for various real-world applications. Let's explore some practical examples.

Quality Control in Manufacturing

In manufacturing, normal distribution plots are often used to analyze product specifications and quality control measures.

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

# Generate sample data for product measurements
np.random.seed(42)
measurements = np.random.normal(loc=100, scale=2, size=1000)

# Calculate mean and standard deviation
mean = np.mean(measurements)
std = np.std(measurements)

# Create the plot
plt.figure(figsize=(12, 6))

# Plot histogram of measurements
plt.hist(measurements, bins=30, density=True, alpha=0.7, color='skyblue', edgecolor='black', label='Product Measurements')

# Plot theoretical normal distribution
x = np.linspace(mean - 4*std, mean + 4*std, 100)
y = stats.norm.pdf(x, mean, std)
plt.plot(x, y, 'r-', lw=2, label='Theoretical Normal')

# Add specification limits
lower_limit, upper_limit = 95, 105
plt.axvline(lower_limit, color='g', linestyle='--', label='Specification Limits')
plt.axvline(upper_limit, color='g', linestyle='--')

plt.title('How to Plot a Normal Distribution with Matplotlib in Python: Quality Control')
plt.xlabel('Measurement')
plt.ylabel('Density')
plt.legend()
plt.text(100, 0.05, 'how2matplotlib.com', fontsize=12, alpha=0.7)
plt.show()

Output:

How to Plot a Normal Distribution with Matplotlib in Python

This example simulates product measurements and plots them against a theoretical normal distribution, along with specification limits, to visualize quality control in a manufacturing process.

Financial Risk Analysis

Normal distribution plots are widely used in finance for risk analysis and portfolio management.

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

# Generate sample returns data
np.random.seed(42)
returns = np.random.normal(loc=0.05, scale=0.1, size=1000)

# Calculate Value at Risk (VaR) at 95% confidence level
var_95 = np.percentile(returns, 5)

# Create the plot
plt.figure(figsize=(12, 6))

# Plot histogram of returns
plt.hist(returns, bins=30, density=True, alpha=0.7, color='skyblue', edgecolor='black', label='Returns Distribution')

# Plot theoretical normal distribution
x = np.linspace(min(returns), max(returns), 100)
y = stats.norm.pdf(x, np.mean(returns), np.std(returns))
plt.plot(x, y, 'r-', lw=2, label='Theoretical Normal')

# Add VaR line
plt.axvline(var_95, color='g', linestyle='--', label=f'95% VaR: {var_95:.2f}')

plt.title('How to Plot a Normal Distribution with Matplotlib in Python: Financial Risk Analysis')
plt.xlabel('Returns')
plt.ylabel('Density')
plt.legend()
plt.text(0, 1, 'how2matplotlib.com', fontsize=12, alpha=0.7)
plt.show()

Output:

How to Plot a Normal Distribution with Matplotlib in Python

This example simulates financial returns and visualizes their distribution along with the Value at Risk (VaR) at a 95% confidence level.

Conclusion

In this comprehensive guide, we've explored how to plot a normal distribution with Matplotlib in Python, covering a wide range of techniques and applications. From basic plots to advanced customization and real-world examples, you now have the tools and knowledge to effectively visualize normal distributions in your data science projects.

Remember that while the normal distribution is a powerful and widely used model, it's essential to always check your data's actual distribution and not assume normality. The visualization techniques we've covered can help you assess whether your data follows a normal distribution and make informed decisions about your statistical analyses.

Pin It