本文为 《Scientific VisualisationPython & Matplotlib》by Nicolas P 一书的学习手记,旨在使用Python &Matplotlib工具进行图表的科学可视化
import scipy
import numpy as np
import matplotlib.pyplot as plt
import sys; print(sys.version)
import matplotlib; print(matplotlib.__version__)
本文使用
- Python 3.7.4
- Numpy 1.16.4
- Scipy 1.3.0
- Matplotlib 3.1.0
背景
- 科学可视化有很多工具组成
- 有一些专门用于web的,有一些是专门用于桌面
- 有一些是用于2D/3D目标或者大数据的可视化渲染
- Matplotlib 最早是由John D. Hunter编写,并在2003年发布
- 2012年,Hunter去世后,由Michael Droettboom主导Matplotlib 的开发
- 2014年后,有Thomas Caswell负责主导Matplotlib 开发
- 最新的版本是支持Python2 Python3的 Matplotlib 3.6.0版本(2022/09/16) 【Matplotlib 官网】
The initial goal was to replace the popular Matlab graphics engine and to support different platforms, to have high quality raster and vector output, to provide support for mathematical expressions and to work interactively from the shell.
20年后,Matplotlib 初心不变,一直秉承着最初的设计理念,如今Matplotlib 已经成为Python科学可视化的事实标准了。
基本概念
一个基本的图表有很多元素组成,而很多时候用户不必关系每一个图表元素,Matplotlib 会为图表设置很多默认值,用户只需要根据自己需求设计即可,比如最简单的一个图表可以表示为:
import matplotlib.pyplot as plt
plt.plot(range(10))
plt.show()
主要元素,详细使用可以参考: 【Matplotlib API使用wiki】
Figure
- 一个图表最重要的元素当然就是 Figure对象自身
- 当创景一个图表的是,可以指定它的尺寸,背景/前景,标题等等
Axes
- 次重要的图表元素,也可以叫 subplot, 它来表示最终数据实际渲染的区域
- 每一个图可以有多个 axes, 每一个axes有上下左右四个边 (spines)
- 每一个spines可以设置 大小不同的刻度(ticks)和标签 (label), 一般默认边只有 底侧和左侧有刻度和标签
Axis
- 被标记了刻度和标签的 spines叫做 axis
- 水平的叫 xaxis, 垂直的叫 yaxis
Artist
- 简单的Artist对象是标准的绘图元件,例如Line2D,Rectangle,Text,AxesImage等
- 容器类型包含多个Artist对象使他们组织成一个整体例如Axis,Axes,Figure对象
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
fig.subplots_adjust(top=0.8)
ax1 = fig.add_subplot(211)
ax1.set_ylabel('volts')
ax1.set_title('a sine wave')
t = np.arange(0.0, 1.0, 0.01)
s = np.sin(2*np.pi*t)
line, = ax1.plot(t, s, color='blue', lw=2)
# Fixing random state for reproducibility
np.random.seed(999)
ax2 = fig.add_axes([0.15, 0.1, 0.7, 0.3])
n, bins, patches = ax2.hist(np.random.randn(1000), 50,
facecolor='yellow', edgecolor='yellow')
ax2.set_xlabel('time (s)')
plt.show()
Scales & Projections
- Matplotlib提供四种不同的比例尺 linear, log, symlog and logit
- Projections 指坐标系的映射,比如从笛卡尔坐标系映射到极坐标系
ax.set_xscale("log")
ax = plt.subplot(1, 1, 1, projection='polar')
ax = plt.subplot(1, 1, 1, projection='3d')
排版
- 如果新安装了字体,需要重新rebuild
import matplotlib.font_manager
matplotlib.font_manager._rebuild()
图表设计
图表设计的10个原则
- Rule 1: 清楚的受众是谁
- Rule 2: 能够清楚辨识你要传达的信息
- Rule 3: 调整图表使得适合所呈现的介质
- Rule 4: 图表一定要有标题
- Rule 5: 不要太依赖默认参数
- Rule 6: 有效地使用图表的颜色
- Rule 7: 不要用图表来误导读者
- Rule 8: 避免图表垃圾,不要有不必要的信息出现在图表中
- Rule 9: Message Trumps Beauty
适当控制默认参数
import numpy as np
import matplotlib.pyplot as plt
X = np.linspace(-np.pi, np.pi, 256, endpoint=True) C, S = np.cos(X), np.sin(X)
plt.plot(X, C)
plt.plot(X, S)
plt.show()
## 设置 图表样式Style文件
figure.figsize: 6,2.5
figure.edgecolor: black
figure.facecolor: ffffff
axes.linewidth: 1
axes.facecolor: ffffff
axes.ymargin: 0.1
axes.spines.bottom: True
axes.spines.left: True
axes.spines.right: False
axes.spines.top: False
font.sans-serif: Fira Sans Condensed
axes.grid: False
grid.color: black
grid.linewidth: .1
xtick.bottom: True
xtick.top: False
xtick.direction: out
xtick.major.size: 5
xtick.major.width: 1
xtick.minor.size: 3
xtick.minor.width: .5
xtick.minor.visible: True
ytick.left: True
ytick.right: False
ytick.direction: out
ytick.major.size: 5
ytick.major.width: 1
ytick.minor.size: 3
ytick.minor.width: .5
ytick.minor.visible: True
lines.linewidth: 2
lines.markersize: 5
# 直接使用自定义style绘制图表
plt.style.use("./mystyle.txt")
fig = plt.figure(linewidth=1)
ax = plt.subplot(1,1,1,aspect=1)
ax.plot(X, np.cos(X), label="cosine")
ax.plot(X, np.sin(X), label="sine")
ax.legend() // 图例
ax.set_yticks([-1,0,1])
// 直接自定义一些少量的参数
// 刻度和标签
ax.set_yticks([-1,1])
ax.set_xticklabels(["-1", "+1"])
ax.set_xticks([-np.pi, -np.pi/2, np.pi/2, np.pi])
ax.set_xticklabels(["π-", "π-/2", "π+/2", "π+"])
// 隐藏边线
ax.spines['bottom'].set_position(('data',0))
ax.spines['left'].set_position(('data',0))
//坐标轴的箭头
ax.plot(1, 0, ">k",
transform=ax.get_yaxis_transform(), clip_on=False)
ax.plot(0, 1, "^k",
transform=ax.get_xaxis_transform(), clip_on=False)