创建 Figure:
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(4,5))
<Figure size 288x360 with 0 Axes>
以上代码新建了一个 figure 实例。参数 figszie=(4,5) 代表图像的宽、高分别为 400、500 像素。
创建 Axes:在 figure 实例中增加一个 axes 实例:
ax = fig.gca()
gca 代表 get current axes,是最简单的办法。
也可以用:
ax = fig.add_subplot(111)
其中 111 代表本 axes 实例是一行、一列的第一个元素。或者
ax = fig.add_axes([0.15,0.15,0.8,0.8])
用这种方法可以指定坐标轴的大小和位置。 [0.15,0.15,0.8,0.8] 代表到边界的距离和坐标轴的宽、高占整个图片宽高的百分比。
axes 类的 plot() 方法是最常用的绘制平面图的方法。例如:
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(1,5,0.1)
y1 = np.sin(x)
y2 = np.cos(x)
fig = plt.figure(figsize=(9,6))
ax = fig.gca()
ax.plot(x,y1,'r-')
ax.plot(x,y2,'bo')
plt.show()
axes.plot()
方法支持的参数有:
fmt='ro-'
。这里支持线和点的标记结合,比如 -(直线)、--(虚线)、:(点线)markerfacecolor='b'
markeredgecolor='b'
markeredgewidth=1
markersize=2.5
linewidth=0.6
alpha=0.5
label='sin(x)'
Matplotlib 支持的颜色代码有:
Matplotlib 支持的标记的形状有:
除此之外还有 x(叉)、d(小菱形)、D(大菱形)、h(竖六边形) H(横六边形)
Matplotlib 支持的线的形状、线的端点的形状、虚线的端点的形状有:
画直方图可以用 axes.hist()
方法。例如:
import numpy as np
x = np.random.rand(100)
fig = plt.figure(figsize=(9,6))
ax = fig.gca()
ax.hist(x, bins=10)
plt.show()
画阶梯图可以用 axes.step()
方法。例如:
import numpy as np
x = np.arange(1,5,0.1)
y1 = np.sin(x)
y2 = np.cos(x)
fig = plt.figure(figsize=(9,6))
ax = fig.gca()
ax.step(x, y1, where='mid')
plt.show()
其中 where 可取值有 ‘pre’, ‘post’, ‘mid’ 分别表示阶梯的“平台”在这个 x 值之前、之后还是中间。
Axes 的 errorbar()
方法绘制误差棒。例如:
import numpy as np
x = np.arange(1,5,0.1)
y = np.sin(x)
errors = np.random.rand(x.size)
fig = plt.figure(figsize=(9,6))
ax = fig.gca()
ax.errorbar(x, y, errors, fmt='ro-')
plt.show()
errorbar()
方法的完整调用:
matplotlib.pyplot.errorbar(x, y, yerr=None, xerr=None, fmt='', ecolor=None, elinewidth=None, capsize=None, barsabove=False, lolims=False, uplims=False, xlolims=False, xuplims=False, errorevery=1, capthick=None, *, data=None, **kwargs)
支持的参数:
rcParams["errorbar.capsize"]
取值可以用 axes 对象中的 plot_date()
方法画时间序列图。
字符串转换成时间序列有两种方法:
dateutil
包的 parser.parse()
函数将字符串处理成由 datetime 对象组成的列表。接着可以用 pylab
包的 date2num()
函数或者 matplotlib
包 dates
模块里的 date2num()
把时间序列转换为浮点数,用作 plot_date()
的输入。例如:import dateutil.parser
import matplotlib.dates as mdates
import numpy as np
x_lst = np.arange(7)
y_lst = np.sin(x_lst)
date_lst = ['2018-01-01T22:45:56', '2018-01-01T23:56:56', '2018-01-02T01:12:21', '2018-01-02T02:30:14',
'2018-01-02T03:33:21', '2018-01-02T04:35:45', '2018-01-02T05:40:11']
dates = [dateutil.parser.parse(s) for s in date_lst]
datenums = mdates.date2num(dates)
fig = plt.figure(figsize=(9,6))
ax = fig.gca()
ax.plot_date(datenums, y_lst ,'r-')
plt.show()
matplotlib
包 dates
模块里的 datestr2num()
函数把字符串序列转换成浮点数另一种方法是把 x 或 y 转换成浮点数后,先用普通的 plot()
方法画图,而后再用 xaxis_date()
或 yaxis_date()
方法把对应的轴转换为时间轴。例如:import matplotlib.dates as mdates
date = ['3 Jan 2013', '4 Jan 2013', '5 Jan 2013', '6 Jan 2013', '7 Jan 2013']
time = ['16:44:00', '16:45:00', '16:46:00', '16:47:00', '16:48:00']
x = mdates.datestr2num(date)
y = mdates.datestr2num(time)
fig = plt.figure(figsize=(9,6))
ax = fig.gca()
ax.plot(x, y, 'ro-')
ax.xaxis_date()
ax.yaxis_date()
plt.show()
格式化时间轴:在 plot_date()
之后可以用 fig.autofmt_xdate()
自动格式化时间轴。
指定时间轴刻度的大小需要使用 matplotlib 包的 dates 模块中的一些列时间间隔对象。例如:
import matplotlib.dates as mdates
x_lst = np.arange(7)
y_lst = np.sin(x_lst)
date_lst = ['2018-01-01T22:45:56', '2018-01-01T23:56:56', '2018-01-02T01:12:21', '2018-01-02T02:30:14',
'2018-01-02T03:33:21', '2018-01-02T04:35:45', '2018-01-02T05:40:11']
dates = [dateutil.parser.parse(s) for s in date_lst]
datenums = mdates.date2num(dates)
fig = plt.figure(figsize=(9,6))
ax = fig.gca()
ax.plot(datenums, y_lst, 'r-')
ax.xaxis_date()
ax.xaxis.set_major_locator(mdates.HourLocator())
ax.xaxis.set_minor_locator(mdates.MinuteLocator(byminute=np.arange(0,60,10)))
plt.show()
上面的例子表示大刻度为每个小时一个,小刻度为每10分钟一个。类似的 locator 还有:
例如,YearLocator()
表示刻度位于每年的 1 月 1 日处;
YearLocator(5, month=7, day=4)
表示刻度位于每年的 7 月 4 日。
其余的用法略有区别,例如 MinuteLocator(byminute=np.arange(0, 10, 60))
表示刻度为每 10 分钟一个,位于 0, 10, 20, ... 50 处。
可以用 axes.scatter()
方法画不同颜色的散点图。
ax.scatter(x_lst, logg_lst, c=c_lst, s=radius_lst, alpha=0.75, cmap='jet')
其中各输入参数:
lw=0
edgecolor='r'
把边框设为红色用 axes.imshow()
方法画平面二维图像
axes.imshow()
aspect='auto'
Axes()
对象的 quiver()
方法可以绘制箭头。它的调用有 4 种方法:
quiver(U, V, **kw)
quiver(U, V, C, **kw)
quiver(X, Y, U, V, **kw)
quiver(X, Y, U, V, C, **kw)
其中 X,Y 是箭头尾部的数据值(可以是 1-D 或者 2-D 数组);U,V 是箭头矢量;C 是颜色。可选参数有:
可以用 figure.colorbar()
方法在 axes.imshow()
或者 axes.scatter()
画的图上添加颜色棒 (colorbar)
fig = plt.figure(figsize=(12,8))
ax = fig.gca()
data = np.random.rand(50,50)*50000
cax = ax.imshow(data)
cbar = fig.colorbar(cax)
plt.show()
在这一节中,我们结合天文绘图中的一些实例来演示Matplotlib的用法
首先导入需要用到的python软件包
import pandas as pd
from astropy.table import Table
import matplotlib.pyplot as plt
import numpy as np
接下来我们用已知的系外行星表格为例,演示散点图和天空投影图的绘制方法。
首先到 http://exoplanet.eu/ 网站上下载系外行星表格,文件名为 exoplanet.eu_catalog.csv
。这是一个csv格式的文件,包含已知的系外行星的各种参数。
用 pandas 的 read_csv()
函数读入这个文件,并用 astropy.table 模块转换成 Astropy 格式的表格:
df = pd.read_csv('exoplanet.eu_catalog.csv')
t = Table.from_pandas(df)
print(t)
print(t.colnames)
# name planet_status ... star_alternate_names ---------- ------------- ... ---------------------------------------------- 11 Com b Confirmed ... -- 11 Oph b Confirmed ... Oph 1622-2405, Oph 11A 11 UMi b Confirmed ... -- 14 And b Confirmed ... -- 14 Her b Confirmed ... -- 14 Her c Confirmed ... -- 16 Cyg B b Confirmed ... -- ... ... ... ... tau Gem b Confirmed ... -- ups And b Confirmed ... -- ups And c Confirmed ... -- ups And d Confirmed ... -- ups And e Confirmed ... -- ups Leo b Confirmed ... -- zet Del B Confirmed ... HD 196180, HIP 101589, 2MASS J20351852+1440272 Length = 5156 rows ['# name', 'planet_status', 'mass', 'mass_error_min', 'mass_error_max', 'mass_sini', 'mass_sini_error_min', 'mass_sini_error_max', 'radius', 'radius_error_min', 'radius_error_max', 'orbital_period', 'orbital_period_error_min', 'orbital_period_error_max', 'semi_major_axis', 'semi_major_axis_error_min', 'semi_major_axis_error_max', 'eccentricity', 'eccentricity_error_min', 'eccentricity_error_max', 'inclination', 'inclination_error_min', 'inclination_error_max', 'angular_distance', 'discovered', 'updated', 'omega', 'omega_error_min', 'omega_error_max', 'tperi', 'tperi_error_min', 'tperi_error_max', 'tconj', 'tconj_error_min', 'tconj_error_max', 'tzero_tr', 'tzero_tr_error_min', 'tzero_tr_error_max', 'tzero_tr_sec', 'tzero_tr_sec_error_min', 'tzero_tr_sec_error_max', 'lambda_angle', 'lambda_angle_error_min', 'lambda_angle_error_max', 'impact_parameter', 'impact_parameter_error_min', 'impact_parameter_error_max', 'tzero_vr', 'tzero_vr_error_min', 'tzero_vr_error_max', 'k', 'k_error_min', 'k_error_max', 'temp_calculated', 'temp_calculated_error_min', 'temp_calculated_error_max', 'temp_measured', 'hot_point_lon', 'geometric_albedo', 'geometric_albedo_error_min', 'geometric_albedo_error_max', 'log_g', 'publication', 'detection_type', 'mass_detection_type', 'radius_detection_type', 'alternate_names', 'molecules', 'star_name', 'ra', 'dec', 'mag_v', 'mag_i', 'mag_j', 'mag_h', 'mag_k', 'star_distance', 'star_distance_error_min', 'star_distance_error_max', 'star_metallicity', 'star_metallicity_error_min', 'star_metallicity_error_max', 'star_mass', 'star_mass_error_min', 'star_mass_error_max', 'star_radius', 'star_radius_error_min', 'star_radius_error_max', 'star_sp_type', 'star_age', 'star_age_error_min', 'star_age_error_max', 'star_teff', 'star_teff_error_min', 'star_teff_error_max', 'star_detected_disc', 'star_magnetic_field', 'star_alternate_names']
接下来,我们选取其中用视向速度方法(Radial Velocity)和凌星方法(Transit)发现的系外行星,并提取他们的RA、Dec
m = t['detection_type']=='Radial Velocity'
t1 = t[m]
ra = t1['ra']
dec = t1['dec']
Vmag = t1['mag_v']
m2 = t['detection_type']=='Primary Transit'
t2 = t[m2]
ra2 = t2['ra']
dec2 = t2['dec']
Vmag2 = t2['mag_v']
接下来把这些系外行星的坐标用不同颜色画在一张图上
fig = plt.figure(figsize=(14,7))
ax = fig.gca()
ax.scatter(ra, dec, alpha=0.5, s=5)
ax.scatter(ra2, dec2, alpha=0.5, s=5)
ax.set_xlabel('RA (deg)')
ax.set_ylabel('Dec (deg)')
plt.show()
下面改用 Hammer 投影:
fig = plt.figure(figsize=(12,6))
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], projection='hammer')
ax.plot(np.pi-np.deg2rad(ra), np.deg2rad(dec), 'o', ms=3, alpha=0.6)
ax.plot(np.pi-np.deg2rad(ra2), np.deg2rad(dec2), 'o', ms=3, alpha=0.6)
plt.show()