图表美化:样式与颜色

好的图表不仅要数据准确,还要美观易读。Matplotlib 提供了丰富的样式和颜色定制选项, 让你可以轻松打造专业级别的可视化作品。本章将全面介绍如何应用预定义样式、自定义颜色、 使用颜色映射以及调整透明度等,让你的图表焕然一新。

🎨 1. 使用预定义样式

Matplotlib 内置了多种样式,可以一键改变图表的整体外观。使用 plt.style.available 查看所有可用样式:

import matplotlib.pyplot as plt
import numpy as np

print(plt.style.available)  # 输出样式列表

应用样式使用 plt.style.use('样式名称')

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

plt.style.use('ggplot')  # 使用 ggplot 风格
plt.plot(x, y1, label='sin')
plt.plot(x, y2, label='cos')
plt.legend()
plt.title('ggplot 样式')
plt.show()

plt.style.use('seaborn-v0_8-darkgrid')  # 使用 seaborn 暗色网格风格
plt.plot(x, y1, label='sin')
plt.plot(x, y2, label='cos')
plt.legend()
plt.title('seaborn-darkgrid 样式')
plt.show()
✔️ 常用样式:'ggplot', 'seaborn', 'bmh', 'classic', 'dark_background' 等。

🌈 2. 自定义颜色

Matplotlib 接受多种颜色表示方式:

  • 颜色名称:如 'red', 'blue', 'green'(完整列表见 官方文档
  • 缩写字母:'b' (蓝), 'g' (绿), 'r' (红), 'c' (青), 'm' (品红), 'y' (黄), 'k' (黑), 'w' (白)
  • 十六进制字符串:如 '#ff5733'
  • RGB 元组:取值范围 0-1,如 (0.1, 0.2, 0.5)
  • 灰度字符串:如 '0.5' 表示中间灰
示例:不同颜色表示法
plt.plot(x, y1, color='red', label='red')           # 颜色名称
plt.plot(x, y2, color='#00ff00', label='#00ff00')   # 十六进制
plt.plot(x, y1*0.5, color=(0.2, 0.4, 0.8), label='RGB')  # RGB元组
plt.plot(x, y2*0.5, color='0.3', label='gray')      # 灰度
plt.legend()
plt.title('多种颜色表示法')
plt.show()

✏️ 3. 设置线条和标记颜色

plot 函数中,可以分别指定线条颜色和标记颜色:

plt.plot(x, y1, color='blue', marker='o', markerfacecolor='red',
         markeredgecolor='black', markersize=8, linewidth=2)
plt.title('线条与标记颜色')
plt.show()
✔️ markerfacecolormarkeredgecolor 分别控制标记内部和边缘颜色。

🗺️ 4. 颜色映射 (Colormap)

颜色映射将数据值映射到颜色,常用于散点图、热力图、等高线图等。通过 cmap 参数指定:

# 散点图颜色映射
x = np.random.randn(200)
y = np.random.randn(200)
z = x**2 + y**2  # 第三个维度

plt.scatter(x, y, c=z, cmap='viridis', s=50)
plt.colorbar(label='距离平方')
plt.title('散点图颜色映射 (viridis)')
plt.show()
✔️ 常用颜色映射:'viridis', 'plasma', 'inferno', 'magma', 'cividis'(顺序),'coolwarm', 'RdBu'(发散)。

颜色映射也可以用于线条(通过将线条分段着色),但更常见于图像和散点。

🔮 5. 透明度 (alpha)

alpha 参数控制图形元素的透明度,取值范围 0(完全透明)到 1(完全不透明)。当多个元素重叠时,透明度有助于观察叠加效果:

x = np.random.randn(1000)

plt.hist(x, bins=30, alpha=0.5, label='alpha=0.5')
plt.hist(x+1, bins=30, alpha=0.5, label='alpha=0.5')
plt.legend()
plt.title('透明度示例')
plt.show()

🔄 6. 颜色循环

当绘制多条曲线而未指定颜色时,Matplotlib 会自动循环使用一组默认颜色。可以使用 plt.rcParams['axes.prop_cycle'] 查看或修改循环规则:

# 查看当前颜色循环
print(plt.rcParams['axes.prop_cycle'].by_key())

# 绘制多条曲线,自动循环颜色
for i in range(1, 6):
    plt.plot(x, np.sin(i*x), label=f'sin({i}x)')
plt.legend()
plt.title('默认颜色循环')
plt.show()

🎨 7. 自定义颜色循环

可以通过 cycler 模块设置自定义的颜色循环:

from cycler import cycler

# 自定义颜色列表
custom_colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd']
plt.rcParams['axes.prop_cycle'] = cycler(color=custom_colors)

for i in range(1, 6):
    plt.plot(x, np.sin(i*x), label=f'sin({i}x)')
plt.legend()
plt.title('自定义颜色循环')
plt.show()

# 恢复默认
plt.rcParams['axes.prop_cycle'] = cycler(color=plt.rcParamsDefault['axes.prop_cycle'].by_key()['color'])
✔️ 也可以同时设置颜色和线型循环:cycler(color=custom_colors) + cycler(linestyle=['-','--',':','-.'])

📈 8. 高级:使用颜色映射为线条着色

通过将线条分割成多个线段并为每个线段分配不同颜色,可以创建颜色随数值变化的线条:

from matplotlib.collections import LineCollection

x = np.linspace(0, 4*np.pi, 500)
y = np.sin(x)

# 创建线段集合
points = np.array([x, y]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)

norm = plt.Normalize(0, 4*np.pi)
lc = LineCollection(segments, cmap='viridis', norm=norm)
lc.set_array(x[:-1])  # 用x值作为颜色映射的依据

fig, ax = plt.subplots()
ax.add_collection(lc)
ax.set_xlim(x.min(), x.max())
ax.set_ylim(-1.5, 1.5)
plt.colorbar(lc, label='x 值')
plt.title('线条颜色随x变化')
plt.show()
✔️ 使用 LineCollection 可以为线条的不同段赋予不同颜色。

🖼️ 9. 背景色和画布颜色

可以通过 ax.set_facecolor() 设置坐标区背景色,fig.patch.set_facecolor() 设置整个画布背景色:

fig, ax = plt.subplots()
ax.plot(x, y1)
ax.set_facecolor('lightyellow')          # 坐标区背景
fig.patch.set_facecolor('lightblue')     # 画布背景
plt.title('自定义背景色')
plt.show()

🏆 10. 综合示例

import matplotlib.pyplot as plt
import numpy as np
from cycler import cycler

# 设置样式和颜色循环
plt.style.use('seaborn-v0_8-darkgrid')
custom_colors = ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00']
plt.rcParams['axes.prop_cycle'] = cycler(color=custom_colors)

# 生成数据
x = np.linspace(0, 2*np.pi, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.sin(2*x)
y4 = np.cos(2*x)
y5 = np.sin(x) * np.cos(x)

# 绘制
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(x, y1, linewidth=2, label='sin(x)')
ax.plot(x, y2, linewidth=2, label='cos(x)')
ax.plot(x, y3, linewidth=2, label='sin(2x)')
ax.plot(x, y4, linewidth=2, label='cos(2x)')
ax.plot(x, y5, linewidth=2, label='sin(x)cos(x)')

# 添加图例和标题
ax.legend(loc='upper right', fontsize=10, frameon=True, shadow=True)
ax.set_title('综合样式与颜色示例', fontsize=16, pad=15)
ax.set_xlabel('x (rad)')
ax.set_ylabel('y')

# 设置背景色
ax.set_facecolor('#f0f0f0')

# 添加网格
ax.grid(True, linestyle='--', alpha=0.6)

plt.tight_layout()
plt.show()
✔️ 综合运用了样式、自定义颜色循环、网格、背景色等。

💾 11. 保存图表

使用 savefig() 保存包含样式和颜色的图表:

plt.savefig('styled_plot.png', dpi=300, bbox_inches='tight')

掌握样式和颜色的定制后,你可以让图表既专业又美观。下一章我们将学习如何将图表保存为不同格式,以及如何配置图表的输出属性。