You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Plotly/Matplotlib绘制带σ值的正态分布曲线?

Polished Normal Distribution Plots with Matplotlib & Plotly

Got it, let's fix that underwhelming normal distribution plot for you! The core issue with your original code is that you're using raw (even sorted) data points to calculate the PDF. Real-world error data rarely has perfectly evenly spaced values, which leads to jagged, misaligned curves. Below are two robust solutions—one with Matplotlib (great for static reports) and one with Plotly (perfect for interactive exploration)—both including σ markers and clear, publication-ready visuals.

Matplotlib Solution

This approach combines a histogram of your data with a smooth normal curve, plus explicit markers for the mean and ±1σ/±2σ/±3σ ranges:

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

# Assume mydata is your error dataset
mymean = np.mean(mydata)
mystd = np.std(mydata)

# Generate evenly spaced x-values for a smooth curve (3σ range covers ~99.7% of data)
x = np.linspace(mymean - 3*mystd, mymean + 3*mystd, 1000)
# Calculate PDF for these x-values
pdf = stats.norm.pdf(x, mymean, mystd)

# Create figure and axes
fig, ax = plt.subplots(figsize=(10, 6))

# Plot histogram of your data (normalized to match PDF scale)
ax.hist(mydata, bins=30, density=True, alpha=0.6, color='#1f77b4', label='Error Data')
# Plot smooth normal curve
ax.plot(x, pdf, color='#ff7f0e', linewidth=2, label=f'Normal Fit (μ={mymean:.2f}, σ={mystd:.2f})')

# Add vertical lines for mean and σ ranges
ax.axvline(mymean, color='#2ca02c', linestyle='--', linewidth=2, label='Mean (μ)')
ax.axvline(mymean + mystd, color='#d62728', linestyle=':', linewidth=1.5, label='μ+σ')
ax.axvline(mymean - mystd, color='#d62728', linestyle=':', linewidth=1.5)
ax.axvline(mymean + 2*mystd, color='#9467bd', linestyle=':', linewidth=1.5, label='μ+2σ')
ax.axvline(mymean - 2*mystd, color='#9467bd', linestyle=':', linewidth=1.5)
ax.axvline(mymean + 3*mystd, color='#8c564b', linestyle=':', linewidth=1.5, label='μ+3σ')
ax.axvline(mymean - 3*mystd, color='#8c564b', linestyle=':', linewidth=1.5)

# Add labels, title, legend
ax.set_xlabel('Error Value')
ax.set_ylabel('Probability Density')
ax.set_title('Normal Distribution of Error Data with σ Markers')
ax.legend()

plt.tight_layout()
plt.show()

Why this works:

  • We use np.linspace to generate 1000 evenly spaced points across the 3σ range, which ensures a smooth, continuous curve (no jagged edges from raw data gaps).
  • The histogram is normalized (density=True) to match the PDF scale, making it easy to compare the data to the ideal normal fit.
  • Clear markers for mean and σ ranges make the plot informative at a glance.

Plotly Solution

For interactive exploration (zoom, hover tooltips, toggleable elements), Plotly is perfect. This code creates an interactive plot with the same key elements:

import numpy as np
import scipy.stats as stats
import plotly.graph_objects as go

# Assume mydata is your error dataset
mymean = np.mean(mydata)
mystd = np.std(mydata)

# Generate smooth x-values
x = np.linspace(mymean - 3*mystd, mymean + 3*mystd, 1000)
pdf = stats.norm.pdf(x, mymean, mystd)

# Create figure
fig = go.Figure()

# Add histogram
fig.add_trace(go.Histogram(
    x=mydata,
    nbinsx=30,
    histnorm='probability density',
    opacity=0.6,
    name='Error Data',
    marker_color='#1f77b4'
))

# Add normal curve
fig.add_trace(go.Scatter(
    x=x,
    y=pdf,
    mode='lines',
    name=f'Normal Fit (μ={mymean:.2f}, σ={mystd:.2f})',
    line=dict(color='#ff7f0e', width=2)
))

# Add vertical lines for mean and σ ranges
# Mean line
fig.add_vline(x=mymean, line_dash='dash', line_color='#2ca02c', annotation_text='μ', annotation_position='top right')
# ±1σ lines
fig.add_vline(x=mymean + mystd, line_dash='dot', line_color='#d62728', annotation_text='μ+σ', annotation_position='top right')
fig.add_vline(x=mymean - mystd, line_dash='dot', line_color='#d62728')
# ±2σ lines
fig.add_vline(x=mymean + 2*mystd, line_dash='dot', line_color='#9467bd', annotation_text='μ+2σ', annotation_position='top right')
fig.add_vline(x=mymean - 2*mystd, line_dash='dot', line_color='#9467bd')
# ±3σ lines
fig.add_vline(x=mymean + 3*mystd, line_dash='dot', line_color='#8c564b', annotation_text='μ+3σ', annotation_position='top right')
fig.add_vline(x=mymean - 3*mystd, line_dash='dot', line_color='#8c564b')

# Update layout
fig.update_layout(
    title='Interactive Normal Distribution of Error Data',
    xaxis_title='Error Value',
    yaxis_title='Probability Density',
    legend_title='Legend',
    width=900,
    height=500
)

fig.show()

Why this works:

  • Interactive tooltips let you hover to see exact values for the histogram bars and curve points.
  • You can zoom/pan to focus on specific ranges (like the ±1σ region) without regenerating the plot.
  • The histnorm='probability density' setting aligns the histogram with the PDF, just like the Matplotlib version.

内容的提问来源于stack exchange,提问作者ankushbraj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:31:34