matplotlib 小结
因为物理实验作图的原因,我有幸接触了 matplotlib
,配合 scipy
的其他组件,可以完成我所有需要的任务(我的需求都是非常初级的 :-) )。鉴于接下来可能转战 R
,所以特地把最近 matplotlib
的使用经验总结一下。
import
import numpy as np
from pylab import *
from scipy.optimize import leastsq
from matplotlib.font_manager import FontManager
简单的绘图
# 折线图:
plot(x, y)
plot(x, y, '-')
plot(x, y, '-', linewidth=2)
# 散点图
plot(x, y, 'o', markersize=2)
plot(x, y, ',')
最小二乘法拟合
# 拟合函数
def fun(x, p):
k, b = p
return k * x + b
# 差值
def err(p, x, y):
return fun(x, p) - y
# 最小二乘法 [1,1] 为初始的猜测
sq = leastsq(err, [1,1], args=(x, y))
numpy
常用函数
# 把 list 转为 np.array
np.array([1, 2, 3, 4, 5])
# 类似于 range 每隔 interval 生成 [beg, end) 的一个值
np.arange(beg, end, interval)
# 把 [beg, end] 均分为 count 段,默认包含右端点
np.linspace(beg, end, count, endpoint=True)
# np.array 可以直接进行向量化操作
x = np.array([...])
y = np.array([...])
x + y
x - y
x * y
x / y
x ** 2
np.sin(x)
np.sqrt(x)
设置绘制区域及坐标轴样式
# 绘制区域
xlim(-0.020, 0.200)
ylim(-10, 90)
# 只显示两条坐标轴
ax = gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_position('zero')
ax.spines['left'].set_position('zero')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
# 坐标轴名称
xlabel(r"$t \mathrm{(ms)}$")
ylabel(r"$L \mathrm{(mm)}$")
# 设置坐标轴刻度
xticks_list = np.linspace(-0.020, 0.200, 12)
xticks(xticks_list, ['%.2f' % x for x in xticks_list])
yticks_list = np.linspace(-10, 90, 11)
yticks(yticks_list, ['%.0f' % y for y in yticks_list])
# 显示网格
grid(True)
# 另外一种设置方法
fig, ax = subplots()
ax.set_title(r'$\Delta T = 0.01\mathrm{(ms)},\ l = %d\mathrm{m},\ g = %.2f\mathrm{m/s}$' % (l, g))
y_range = np.linspace(rad(-90), rad(90), 13)
ax.set_yticks(y_range)
ax.set_yticklabels([r'$%.0f^{\circ}$' % deg(y) for y in y_range])
ax.set_ylim(-rad(100), rad(100))
ax.set_ylabel(r'$\theta$')
ax.set_xlabel(r'$t\mathrm{(s)}$')
中文文本框
# 中文字体
myfont = matplotlib.font_manager.FontProperties(fname='/Library/Fonts/AdobeSongStd-Light.otf')
#相关系数
corr = np.corrcoef(x, y)[0][1]
# 文本框
bbox_props = dict(boxstyle="square", fc="white", ec="black", lw=2)
# 文本
text1 = "$y=ax+b$\n$a=%.6f$\n$b=%.6f$\n$r=%.6f$" % (sq[0][0], sq[0][1], corr)
ax.text(x0, y0, text1, ha="left", va="center", size=15, bbox=bbox_props)
显示及输出图片
# 预览图片
show()
# 保存图片
savefig('/Users/abcdabcd987/Desktop/figure_1.png', dpi=300)
# 清除图像 释放内存
clf()
标题及图示
# 设置标题
ax.set_title('title')
# plot 设置 label
ax.plot(x, y, '.', label='My Label')
# 显示图示
ax.legend(loc='upper center', prop={'size': 9})
常用绘图功能
# 指定 (r,g,b,a) 颜色
plot(x, y, color=(1, 1, 1, 1))
# 对数坐标
ax.set_yscale('log')
# 极坐标
subplot(polar=True)
plot(x, y)
# 双y轴
fig, ax1 = subplots()
ax1.set_title(r'$\theta = %d^{\circ},\ l = %d\mathrm{m},\ g = %.2f\mathrm{m/s},\ T = %.2f\mathrm{s}$' % (90, l, g, T))
ax1.set_xscale('log')
ax1.set_xlabel(r'$\Delta T\mathrm{(s)}$')
ax1.set_yscale('log')
ax1.set_ylabel('Standard Error')
plot1 = ax1.plot(deltaTs, stds, 'bo', markersize=6, label='Standard Error')
ax2 = twinx()
ax2.set_yscale('log')
ax2.set_ylabel('Calculation Time (s)')
plot2 = ax2.plot(deltaTs, times, 'gs', markersize=6, label='Calculation Time (s)')
plots = plot1 + plot2
plot_labels = [p.get_label() for p in plots]
ax1.legend(plots, plot_labels, loc='upper center', prop={'size': 9})