最近帮朋友用python画了一些图,发现对这块不是很熟悉。每次得不断的在网上查资料,所以想着好好整理一些基本的图形构造方法。现在流行的python制图方法就是matplotlib了,我们也是用这个,我下面会依次介绍曲线图,散点图,直方图以及多子图的方法。此处是代码
曲线图
凡是连续的曲线图都是用plt.plot()函数绘制的,以下是一段最简单的代码:
# 使用plt.plot()绘图。"lw"-线条的宽度;"ls"-线条的风格样式:"-", "--", '-.', ':'
# label-曲线对应的标签,一般在四个边角出现;color-曲线对应的颜色:'b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'
# marker-标记风格,'o', '*, '+'
plt.plot(x, y, lw=2, ls=':', label="xinge", color="r", marker="*")
# 设置图案位置
plt.legend()
plt.show()
plot()函数里的参数我都备注的很清楚了,以下是生成的图片:
这儿还得记住一点:plt.legend()这个函数是必须得加的,否则你的label备注就显示不出来了。比如我的label="xinge",不加legend()函数就看不见啦。
- 调整坐标轴的数值显示范围
plt.xlim(xmin=-2, xmax=12)
plt.ylim(ymin=-2, ymax=2)
2. 设置坐标轴的名称.
# 设置坐标轴的名称.fontsize-字体大小;horizontalalignment-坐标轴名称排列的方向:center’, ‘right’, ‘left’
plt.xlabel("x-axis", fontsize=16, horizontalalignment="center")
plt.ylabel("y-axis", fontsize=16, horizontalalignment="center")
3. 设置水平参考线和垂直参考线
plt.axhline(y=0, lw=2, ls="--", color="g")
plt.axvline(x=0, lw=2, ls="--", color="g")
4. 使用annotate()对曲线添加注释
# 使用annotate()对曲线添加注释
# xy: 指示点的坐标,即我们希望注释箭头指向的点的坐标;
# xytext: 注释文本左端的坐标(不是文本中心的坐标)
# weight: 注释文本的字体粗细风格,'light', 'normal', 'regular', 'book', 'medium', 'roman'
# color: 注释文本的颜色
# arrowstyle: 箭头类型,'->', '|-|', '-|>'
# connectionstyle: 连接类型,'arc3', 'arc', 'angle', 'angle3'
plt.annotate('maximum',
xy=(np.pi * 3 / 2, -1),
xytext=(np.pi * 3 / 2 - 0.6, -0.7),
weight='light',
color='r',
arrowprops={
'arrowstyle': '->',
'connectionstyle': 'arc3',
'color': 'r',
'alpha': 0.3
})
5. 使用text生成绝对位置的注释
plt.text(np.pi * 3 / 2 - 0.7, -1.7, s='minimum', weight='regular', color='r', fontsize=12)
就大概介绍这些基础的函数,这是最终生成的图片:
散点图
画散点图使用plt.scatter()函数,里面的参数会和plot()函数有些区别,其他的方法则是都一样了。
plt.scatter(x, y, lw=2, marker="o", label="xinge", color="r")
# 设置图案位置
plt.legend()
plt.show()
以下是效果图。
直方图
直方图使用plt.hist()方法的。说实话显示图形很简单,也是只需要一行代码,如下所示:
# histtype: 可选{'bar', 'barstacked', 'step', 'stepfilled'}之一,默认为bar,推荐使用默认配置,step使用的是梯状,
plt.hist(x, bins, color='deepskyblue', width=width, alpha=0.7, histtype="bar")
但一般情况下,我们是使用连线将直方图的频数给连接起来。其实这也好做,只要我们获得了直方图中每个小图的数据以及相应频数(x, y坐标),我们就能用plt.plot()函数给勾勒出来了。而plt.hist()函数正好是可以返回每个小图的频数的。
x = np.random.randint(0, 100, 100) # 生成【0-100】之间的100个数据,即 数据集
bins = np.arange(0, 101, 10) # 设置连续的边界值,即直方图的分布区间[0,10],[10,20]...
width = 10 # 柱状图的宽度
# 生成直方图
# density: bool,默认为false,显示的是频数统计结果,为True则显示频率统计结果
# histtype: 可选{'bar', 'barstacked', 'step', 'stepfilled'}之一,默认为bar,推荐使用默认配置,step使用的是梯状,
frequency_each, _, _ = plt.hist(x, bins, color='deepskyblue', width=width, alpha=0.7, histtype="bar")
plt.xlabel('scores')
plt.ylabel('count')
plt.xlim(0, 100) # 设置x轴分布范围
# 利用返回值来绘制区间中点连线
plt.plot(bins[1:] - (width // 2), frequency_each, color='palevioletred')
plt.show()
效果如下:
多子图
其实就是plt.figure()函数加上subplot()函数。请注意:定义一张画布后,如果是要显示多张子图,那么一定要让这块画布将每个子图都添加进去,否则不会显示出来。
x = np.linspace(0, 5)
y1 = np.sin(np.pi * x)
y2 = np.sin(np.pi * x * 2)
# 直接用plt.figure()显示不了子图
plt.figure(num="xinge", figsize=(10, 10))
# subplot()函数返回两个对象。一个是fig画布,一个是ax子图:ax.plot()
fig, ax = plt.subplots(1, 2)
ax[0].plot(x, y1, ls="-", label="sin(pi*x)", c="b")
# 子图设置x,y轴标签时写法不一样。set_xlabel()
ax[0].set_xlabel("x1 label")
ax[0].set_ylabel("y1 value")
ax[0].legend()
ax[1].plot(x, y2, ls="-", label="sin(pi*x*2)", c="r")
ax[1].set_xlabel("x1 label")
ax[1].set_ylabel("y2 value")
ax[1].legend()
plt.show()
效果如下: