当前位置: 代码网 > it编程>前端脚本>Python > Python matplotlib绘制高级图表的完整教学

Python matplotlib绘制高级图表的完整教学

2026年08月08日 Python 我要评论
本章涵盖双 y 轴、误差线、填充图、极坐标、热力图、箱线图、小提琴图等高级图表类型。ax.twinx()— 双 y 轴在同一张图上显示两个不同量纲的数据。import matplotlib

本章涵盖双 y 轴、误差线、填充图、极坐标、热力图、箱线图、小提琴图等高级图表类型。

ax.twinx()— 双 y 轴

在同一张图上显示两个不同量纲的数据。

import matplotlib.pyplot as plt
import numpy as np

fig, ax1 = plt.subplots(figsize=(12, 6))

x = np.arange(12)
revenue = [100, 120, 140, 155, 165, 180, 175, 190, 200, 210, 220, 235]
growth_rate = [3.5, 4.2, 5.1, 4.8, 3.8, 6.2, 4.1, 5.5, 5.9, 6.0, 5.2, 6.8]

# 主轴: 柱状图
ax1.bar(x, revenue, color='steelblue', alpha=0.7, label='revenue')
ax1.set_xlabel('month')
ax1.set_ylabel('revenue (万元)', color='steelblue')
ax1.tick_params(axis='y', labelcolor='steelblue')

# 副轴: 折线图
ax2 = ax1.twinx()
ax2.plot(x, growth_rate, 'r-o', linewidth=2, markersize=8, label='growth')
ax2.set_ylabel('growth rate (%)', color='red')
ax2.tick_params(axis='y', labelcolor='red')
ax2.set_ylim(0, 10)

# 合并图例
lines1, labels1 = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax1.legend(lines1 + lines2, labels1 + labels2, loc='upper left')

fig.tight_layout()

ax.twiny()— 双 x 轴

fig, ax1 = plt.subplots(figsize=(10, 5))

ax1.plot(x, y1, 'b-')
ax1.set_xlabel('x (meters)')

# 上方辅助 x 轴
ax2 = ax1.twiny()
ax2.set_xlabel('x (feet)')
ax2.set_xlim(ax1.get_xlim())
# 自定义刻度映射
ax2.xaxis.set_major_formatter(
    plt.funcformatter(lambda x, p: f'{x * 3.281:.1f}')
)

ax.errorbar()— 误差线

fig, ax = plt.subplots(figsize=(10, 6))

x = np.arange(5)
y = [3.5, 4.7, 6.2, 5.1, 7.8]
yerr = [0.4, 0.6, 0.8, 0.5, 0.7]       # 对称误差
yerr_low = [0.3, 0.4, 0.5, 0.3, 0.6]    # 非对称误差
yerr_high = [0.5, 0.7, 1.0, 0.6, 0.9]

# 基本误差线
ax.errorbar(x, y, yerr=yerr, fmt='o-', capsize=5, capthick=1.5,
            ecolor='red', markerfacecolor='blue', markersize=10,
            linewidth=2, label='measurement')

# 非对称误差
ax.errorbar(x + 0.1, y, yerr=[yerr_low, yerr_high],
            fmt='s-', capsize=5, label='asymmetric')

# x 方向误差
xerr = [0.1, 0.15, 0.2, 0.1, 0.12]
ax.errorbar(x, y, xerr=xerr, yerr=yerr, fmt='o', capsize=5)

ax.legend()
ax.set_xlabel('sample')
ax.set_ylabel('value')

errorbar 参数

ax.errorbar(x, y,
    yerr=none,        # 标量 / 数组 / (low, high) 数组
    xerr=none,        # 同上
    fmt='o-',         # 数据点样式
    ecolor=none,      # 误差线颜色
    elinewidth=none,  # 误差线线宽
    capsize=0,        # 横线帽大小
    capthick=none,    # 横线帽粗细
    barsabove=false,  # 误差线在标记上方
    lolims=false,     # 下误差线为单向箭头
    uplims=false,     # 上误差线为单向箭头
    xlolims=false,    # x 下误差
    xuplims=false,    # x 上误差
    errorevery=1,     # 每 n 个点画误差线
)

fill_between()— 区域填充

fig, axes = plt.subplots(1, 3, figsize=(14, 4))

x = np.linspace(0, 10, 200)
y1 = np.sin(x)
y2 = np.sin(x) + 0.5 * np.random.randn(200)

# 1. 填充到固定值
ax = axes[0]
ax.plot(x, y1)
ax.fill_between(x, y1, 0, alpha=0.3, color='blue')
ax.set_title('fill to 0')

# 2. 填充两条线之间
ax = axes[1]
ax.plot(x, y1, 'b-', label='signal')
ax.plot(x, y2, 'r-', alpha=0.5, label='noisy')
ax.fill_between(x, y1, y2, alpha=0.3, color='purple',
                where=(y2 > y1), interpolate=true)
ax.set_title('fill between lines')

# 3. 带条件填充
ax = axes[2]
ax.plot(x, y1)
ax.fill_between(x, y1, 0,
                where=(y1 >= 0),    # y>0 红色
                alpha=0.5, color='red', label='positive')
ax.fill_between(x, y1, 0,
                where=(y1 < 0),     # y<0 蓝色
                alpha=0.5, color='blue', label='negative')
ax.set_title('conditional fill')
ax.legend()

常用填充模式

# 置信区间带
mu = np.sin(x)
sigma = 0.2 * np.ones_like(x)
ax.plot(x, mu, 'b-')
ax.fill_between(x, mu - 2*sigma, mu + 2*sigma, alpha=0.2, color='b')

# 累加填充(stacked area)
ax.fill_between(x, 0, y1, alpha=0.5, label='a')
ax.fill_between(x, y1, y1 + y2, alpha=0.5, label='b')
ax.fill_between(x, y1 + y2, y1 + y2 + y3, alpha=0.5, label='c')

# 梯度填充
for i in range(10):
    ax.fill_between(x, i * 0.1, (i + 1) * 0.1,
                    alpha=i / 30, color='blue')

极坐标projection='polar'

fig, axes = plt.subplots(1, 3, figsize=(14, 5),
                          subplot_kw={'projection': 'polar'})

# 1. 极坐标线图
ax = axes[0]
theta = np.linspace(0, 2 * np.pi, 100)
r = np.abs(np.sin(3 * theta))
ax.plot(theta, r, 'b-', linewidth=2)
ax.set_title('polar line', va='bottom')

# 2. 极坐标散点
ax = axes[1]
n = 50
theta = 2 * np.pi * np.random.rand(n)
r = np.random.rand(n)
colors = theta
ax.scatter(theta, r, c=colors, s=100, cmap='hsv', alpha=0.75)
ax.set_title('polar scatter')

# 3. 风向玫瑰图(多个柱状图在极坐标)
ax = axes[2]
directions = np.linspace(0, 2 * np.pi, 8, endpoint=false)
speeds = [3, 5, 8, 10, 7, 4, 2, 3]
width = 2 * np.pi / 8
ax.bar(directions, speeds, width=width, color='steelblue',
       alpha=0.7, edgecolor='black')
ax.set_title('wind rose')

极坐标设置

ax = plt.subplot(111, projection='polar')

# 设置起始角度与方向
ax.set_theta_zero_location('n')    # 0° = 北(顶部)
# 'n', 'nw', 'w', 'sw', 's', 'se', 'e', 'ne'

ax.set_theta_direction(-1)         # -1 顺时针, 1 逆时针

# 设置径向轴范围
ax.set_rlim(0, 10)
ax.set_rticks([2, 4, 6, 8, 10])

imshow()— 热力图 / 图像

fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# 1. 矩阵热力图
ax = axes[0]
data = np.random.rand(10, 10)
im = ax.imshow(data, cmap='viridis', aspect='auto', origin='upper')
ax.set_xticks(range(10))
ax.set_yticks(range(10))
ax.set_xlabel('features')
ax.set_ylabel('samples')
plt.colorbar(im, ax=ax, label='value')
ax.set_title('heatmap')

# 2. 相关性矩阵
ax = axes[1]
corr = np.random.randn(8, 8)
# 对称化
corr = (corr + corr.t) / 2
np.fill_diagonal(corr, 1)

im = ax.imshow(corr, cmap='rdbu_r', vmin=-1, vmax=1, aspect='auto')
# 在每个格子上添加数值
for i in range(8):
    for j in range(8):
        ax.text(j, i, f'{corr[i, j]:.2f}', ha='center', va='center',
                fontsize=8, color='black' if abs(corr[i, j]) < 0.7 else 'white')

plt.colorbar(im, ax=ax, label='correlation')
ax.set_title('correlation matrix')

boxplot()/violinplot()— 分布图

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

# 生成数据
data = [np.random.normal(0, std, 100) for std in range(1, 5)]
labels = ['group a', 'group b', 'group c', 'group d']

# 1. 箱线图
ax = axes[0]
bp = ax.boxplot(data, labels=labels, patch_artist=true,
                showmeans=true, showfliers=true)

# 自定义颜色
colors = ['lightblue', 'lightgreen', 'lightyellow', 'lightcoral']
for patch, color in zip(bp['boxes'], colors):
    patch.set_facecolor(color)

ax.set_title('box plot')
ax.set_ylabel('value')
ax.grid(axis='y', alpha=0.5)

# 2. 小提琴图
ax = axes[1]
vp = ax.violinplot(data, showmeans=true, showmedians=true)

# 自定义颜色
for i, body in enumerate(vp['bodies']):
    body.set_facecolor(colors[i])
    body.set_alpha(0.7)

ax.set_xticks([1, 2, 3, 4])
ax.set_xticklabels(labels)
ax.set_title('violin plot')
ax.set_ylabel('value')
ax.grid(axis='y', alpha=0.5)

更多箱线图参数

ax.boxplot(data,
    vert=true,             # 垂直(true) / 水平(false)
    patch_artist=true,     # 是否填充箱体颜色
    showmeans=true,        # 显示均值(绿色三角形)
    meanline=false,        # 均值用线而非点
    showfliers=true,       # 显示异常值
    showbox=true,          # 显示箱体
    showcaps=true,         # 显示横线帽
    notch=false,           # 是否显示凹槽(中位数的 ci)
    widths=0.5,            # 箱体宽度
    whis=1.5,              # 须的范围(iqr 倍数)
    bootstrap=10000,       # 凹槽 ci 的 bootstrap 次数
)

stackplot()— 堆积面积图

fig, ax = plt.subplots(figsize=(10, 6))

x = np.arange(10)
y1 = np.random.randint(1, 10, 10)
y2 = np.random.randint(1, 10, 10)
y3 = np.random.randint(1, 10, 10)

ax.stackplot(x, y1, y2, y3,
             labels=['product a', 'product b', 'product c'],
             colors=['steelblue', 'coral', 'seagreen'],
             alpha=0.7)
ax.legend(loc='upper left')
ax.set_title('stacked area chart')

stem()— 茎叶图

fig, ax = plt.subplots(figsize=(10, 5))

x = np.linspace(0.1, 2 * np.pi, 40)
y = np.exp(-0.3 * x) * np.sin(x)

markerline, stemlines, baseline = ax.stem(x, y)

plt.setp(markerline, 'markerfacecolor', 'red', 'markersize', 8)
plt.setp(stemlines, 'color', 'gray', 'linewidth', 1)
plt.setp(baseline, 'color', 'black', 'linewidth', 1.5)
ax.set_title('stem plot')

step()— 阶梯图

fig, ax = plt.subplots(figsize=(10, 5))

x = np.arange(10)
y = np.random.randint(1, 10, 10)

ax.step(x, y, where='post', label='post (default)')   # 右侧阶梯
ax.step(x, y, where='pre', label='pre')                # 左侧阶梯
ax.step(x, y, where='mid', label='mid')                # 中间阶梯
ax.legend()
ax.set_title('step plot')

broken_barh()— 不连续水平条形图

常用于甘特图/时间线。

fig, ax = plt.subplots(figsize=(10, 4))

# (start, duration) 元组列表
ax.broken_barh([(0, 5), (7, 3), (12, 4)], (10, 5),    # y=10-15
               facecolors=('red', 'yellow', 'orange'))
ax.broken_barh([(2, 6), (9, 5)], (20, 5),              # y=20-25
               facecolors=('blue', 'green'))

ax.set_xlim(0, 20)
ax.set_ylim(5, 30)
ax.set_xlabel('time')
ax.set_yticks([12.5, 22.5])
ax.set_yticklabels(['task a', 'task b'])
ax.set_title('gantt-like chart')

图表类型速查

图表类型函数用途
双y轴ax.twinx()不同量纲对比
误差线ax.errorbar()显示测量误差
区域填充ax.fill_between()置信区间、面积
极坐标projection='polar'方向/角度数据
热力图ax.imshow()矩阵可视化
箱线图ax.boxplot()分布与异常值
小提琴图ax.violinplot()分布密度
堆积面积ax.stackplot()成分占比趋势
茎叶图ax.stem()离散信号
阶梯图ax.step()分段常量
水平条段ax.broken_barh()时间线/甘特图
饼图ax.pie()占比(注意:不推荐 3d 饼图)
雷达图projection='polar' + fill多维对比

以上就是python matplotlib绘制高级图表的完整教学的详细内容,更多关于python matplotlib绘制图表的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com