大数据 爬虫Python AI Sql程序员

Matplotlib 绘2D图

2017-09-04  本文已影响622人  听城

Matplotlib 是一个非常简单而又完善的开源绘图库。那么它到底有多简单呢?

基本知识

首先官方文档奉上
下面,我们通过 3 行代码绘制一张简单的折线图。

from matplotlib import pyplot as plt
plt.plot([1,2,3,4,2,1,5,6,1])
plt.show()
折线图

plt.plot() 是 pyplot 模块下面的直线绘制(折线图)方法类。示例中包含了一个[1,2,3,4,2,1,5,6,1]列表,该列表的值默认为y值,而 x 值会从 0 到 n-1,这也就是为什么你会发现3反而对应的是4。

方法 含义
matplotlib.pyplot.angle_spectrum 绘制电子波谱图
matplotlib.pyplot.bar 绘制柱状图
matplotlib.pyplot.barh 绘制直方图
matplotlib.pyplot.broken_barh 绘制水平直方图
matplotlib.pyplot.contour 绘制等高线图
matplotlib.pyplot.errorbar 绘制误差线
matplotlib.pyplot.hexbin 绘制六边形图案
matplotlib.pyplot.hist 绘制柱形图
matplotlib.pyplot.hist2d 绘制水平柱状图
matplotlib.pyplot.imshow 以图像显示
matplotlib.pyplot.pie 绘制饼状图
matplotlib.pyplot.quiver 绘制量场图
matplotlib.pyplot.scatter 散点图
matplotlib.pyplot.specgram 绘制光谱图
matplotlib.pyplot.subplot 绘制子图

下面,我们就来一些常见类型的图像绘制及参数使用。

from matplotlib import pyplot as plt #载入 pyplot 绘图模块
import numpy as np # 载入数值计算模块

# 在 -2PI 和 2PI 之间等间距生成 1000 个值,也就是 x 坐标
x = np.linspace(-2*np.pi, 2*np.pi, 1000)
# 计算 y 坐标
y = np.sin(x)

# 向方法中 `*args` 输入 x,y 坐标
plt.plot(x, y)
plt.show()
from matplotlib import pyplot as plt #载入 pyplot 绘图模块
import numpy as np # 载入数值计算模块

# 在 -2PI 和 2PI 之间等间距生成 10 个值,也就是 X 坐标
x = np.linspace(-2*np.pi, 2*np.pi, 10)
# 计算 y 坐标
y = np.sin(x)

# 向方法中 `*args` 输入 x,y 坐标
plt.bar(x, abs(y))  # y 值取绝对值
plt.show()
from matplotlib import pyplot as plt #载入 pyplot 绘图模块
import numpy as np # 载入数值计算模块

# x,y 的坐标均有 numpy 在 0 到 1 中随机生成 1000 个值
x = np.random.normal(0,1,1000)
y = np.random.normal(0,1,1000)

# 向方法中 `*args` 输入 X,y 坐标
plt.scatter(x, y)
plt.show()
from matplotlib import pyplot as plt #载入 pyplot 绘图模块

Z = [1, 2, 3, 4, 5]
# 绘图
plt.pie(Z)
plt.show()

但是Matplotlib 默认的样式的确算不上美观。所以,我们需要设置绘图方法的参数,从而画出更漂亮和自己想要的图形。

线型图进阶

我们已经知道了,线型图通过 matplotlib.pyplot.plot(*args, **kwargs) 方法绘出。其中,args 代表数据输入,而 kwargs 的部分就是用于设置样式参数了。

参数 含义
alpha= 设置线型的透明度,从 0.0 到 1.0
color= 设置线型的颜色
fillstyle= 设置线型的填充样式
linestyle= 设置线型的样式
linewidth= 设置线型的宽度
marker= 设置标记点的样式
color =参数值 颜色
b 蓝色
g 绿色
r 红色
w 白色
m 洋红色
y 黄色
k 黑色
linestyle =参数值 线型
'-' 默认实线
'--' 虚线
'-.' 间断线
':' 点状线
marker =参数值 样本点标记
'.' 实心点
',' 像素点
'o' 空心点
'p' 五角形
'x' x 形
'+' + 形

下面我们根据这些属性将我们的三角函数图像重新画一遍

# -*- coding: utf-8 -*

from matplotlib import pyplot as plt  # 载入 pyplot 绘图模块
import numpy as np  # 载入数值计算模块

# 在 -2PI 和 2PI 之间等间距生成 1000 个值,也就是 x 坐标
x = np.linspace(-2 * np.pi, 2 * np.pi, 1000)
# 计算 sin() 对应的纵坐标
y1 = np.sin(x)
# 计算 cos() 对应的纵坐标
y2 = np.cos(x)

# 向方法中 `*args` 输入 X,y 坐标
plt.plot(x, y1, color='r', linestyle='--', linewidth=2, alpha=0.1)
plt.plot(x, y2, color='b', linestyle='-', linewidth=2)
线形图

散点图进阶

参数 含义
s= 散点大小
c= 散点颜色
marker= 散点样式
cmap= 定义多类别散点的颜色
alpha= 点的透明度
edgecolors= 散点边缘颜色

除了线型图以外,散点图也是常用图形之一。例如,我们在使用机器学习算法聚类的时候,往往就会通过散点图将样本数据展示出来。Matplotlib 中,绘制散点图的方法我们已经知道了,那就是 matplotlib.pyplot.scatter()。接下来,我们就看一看它包含有哪些参数。

参数 含义
s= 散点大小
c= 散点颜色
marker= 散点样式
cmap= 定义多类别散点的颜色
alpha= 点的透明度
edgecolors= 散点边缘颜色
# -*- coding: utf-8 -*

from matplotlib import pyplot as plt  # 载入 pyplot 绘图模块
import numpy as np  # 载入数值计算模块

x = np.random.rand(100) # 随机在 0 到 1 之间生成 100 个数值
y = np.random.rand(100) # 随机在 0 到 1 之间生成 100 个数值
colors = np.random.rand(100) # 随机在 0 到 1 之间生成 100 个数值
size = np.random.normal(20, 30, 100) # 随机在 20 到 30 之间生成 100 个数值

# 绘制散点图
plt.scatter(x, y, s=size, c=colors)
plt.show()
plt.show()

饼状图进阶

# -*- coding: utf-8 -*

import matplotlib.pyplot as plt

label = 'Cat', 'Dog', 'Cattle', 'Sheep', 'Horse' # 各类别标签
color = 'r', 'g', 'r', 'g', 'y' # 各类别颜色
size = [1, 2, 3, 4, 5] # 各类别占比
explode = (0, 0, 0, 0, 0.2) # 各类别的偏移半径
# 绘制饼状图
plt.pie(size, colors=color, explode=explode, labels=label, shadow=True, autopct='%1.1f%%')
# 饼状图呈正圆
plt.axis('equal')
# 显示图
plt.show()

组合图

上面演示了三种常见图像的绘制。实际上,我们往往会遇到将几种类型的一样的图放在一张图内显示,也就是组合图的绘制。其实很简单,你只需要将需要或者的组合图样式放在一起就好了,比如柱形图和折线图。

# -*- coding: utf-8 -*

import matplotlib.pyplot as plt

x = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
y_bar = [3, 4, 6, 8, 9, 10, 9, 11, 7, 8]
y_line = [2, 3, 5, 7, 8, 9, 8, 10, 6, 7]

plt.bar(x, y_bar)
plt.plot(x, y_line, '-o', color='y')
plt.show()

子图

子图,就是将几张独立的图放在一张大图中呈现。在一些需要对比的情形下,子图非常有效。
Matplotlib 中,绘制子图的方法为matplotlib.pyplot.subplot(),我们通过该方法来控制各子图的显示顺序。其中规则为subplot(行序号, 列序号, 图序号)

import numpy as np
import matplotlib.pyplot as plt

# 生成数据
x = np.linspace(-2*np.pi, 2*np.pi) 

y1 = np.sin(x)
y2 = np.cos(x)

# 子图 1
plt.subplot(2, 2, 1)
plt.plot(x, y1, 'k')
# 子图 2
plt.subplot(2, 2, 2)
plt.plot(x, y2, 'r')
# 子图 3
plt.subplot(2, 2, 3)
plt.plot(x, y2, 'y')
# 子图 4
plt.subplot(2, 2, 4)
plt.plot(x, y2, 'g')

plt.show()

更为高级的子图画法
首先需要了解一下基础知识
画图需要生成一个figure(可理解为画布或进程),此参数可无需设置,如未设置pyplot会自动帮你创建一个(figure 1)。接下来,要决定在figure中哪个位置画图,画多大的图。这就引入坐标点和大小的概念,整个figure按照X与Y轴横竖来平均切分,以0到1之间的数值来表示。 如:X轴上的0.1,代表了X轴总长自左向右的10%位置。
整个画图区域就是一个axes,通过Axes参数选项可以对画图区域的坐标点与大小进行设置,如未设置会自动帮接近覆盖整个figure的值。在一个figure中可添加多个Axes,就如一个画布中可以画一整副图,又或者可以画四宫图等等。axes参数设置如下:
axes([x,y,xs,ys])#其中x代表在X轴的位置,y代表在Y轴的位置,xs代表在X轴上向右延展的范围大小,yx代表在Y轴中向上延展的范围大小。

import numpy as np
import matplotlib.pyplot as plt

# 生成数据
x = np.linspace(-2 * np.pi, 2 * np.pi)

y1 = np.sin(x)
y2 = np.cos(x)

# 大图
plt.axes([.1, .1, .8, .8])
plt.plot(x, y1, 'k')
# 小图
plt.axes([.6, .6, .3, .3])
plt.plot(x, y2, 'r')

plt.show()

绘制图例

一般情况下,当绘制好图案后,还需要绘制图例。Matplotlib 中,图例可以通过 matplotlib.pyplot.legend() 方法绘制。我们又拿上面的正弦和余弦曲线举例。

# -*- coding: utf-8 -*

from matplotlib import pyplot as plt  # 载入 pyplot 绘图模块
import numpy as np  # 载入数值计算模块

# 生成数据
X = np.linspace(-2 * np.pi, 2 * np.pi, 1000)
y1 = np.sin(X)
y2 = np.cos(X)

# 使用 label= 添加标签
plt.plot(X, y1, color='r', linestyle='--', linewidth=2, label='sin 函数')
plt.plot(X, y2, color='b', linestyle='-', linewidth=2, label='cos 函数')
# 绘制图例
plt.legend(loc='upper left')
plt.show()

在这里,我们需要修改两个地方,也就是通过label=为每一条曲线添加标签。然后,增加一条plt.legend(loc='upper left')就可以了。其中,loc='upper left'是指明图例的位置,例如这里是左上方。你还可以通过 down 和 right 组合实现位置的变换。

图像标注

当我们绘制一些较为复杂的图像时,阅读对象往往很难全面理解图像的含义。而此时,图像标注往往会起到画龙点睛的效果。图像标注,就是在画面上添加文字注释、指示箭头、图框等各类标注元素。

Matplotlib 中,文字标注的方法由 matplotlib.pyplot.text() 实现。最基本的样式为 matplotlib.pyplot.text(x, y, s),其中 x, y 用于标注位置定位,s 代表标注的字符串。除此之外,你还可以通过 fontsize= , horizontalalignment= 等参数调整标注字体的大小,对齐样式等。
下面,我们举一个对柱形图进行文字标注的示例。

# -*- coding: utf-8 -*
from matplotlib import pyplot as plt # 载入绘图模块

x_bar = [10, 20, 30, 40, 50] #柱形图横坐标
y_bar = [0.5, 0.6, 0.7, 0.4, 0.6] #柱形图纵坐标
bars = plt.bar(x_bar, y_bar, color='blue',  width=2) # 绘制柱形图
for i, rect in enumerate(bars):
    x_text = rect.get_x() # 获取柱形图横坐标
    y_text = rect.get_height() + 0.01 # 获取柱子的高度并增加 0.01
    plt.text(x_text, y_text, '%.1f' % y_bar[i]) # 标注文字

plt.show()

除了文字标注之外,还可以通过 matplotlib.pyplot.annotate() 方法向图像中添加箭头等样式标注。接下来,我们向上面的例子中增添一行增加箭头标记的代码。

 # 增加箭头标注
    plt.annotate('Max', xy=(32, 0.6), xytext=(38, 0.6), arrowprops=dict(facecolor='black', width=1, headwidth=7))

上面的示例中,xy=() 表示标注终点坐标,xytext=() 表示标注起点坐标。另外,arrowprops=() 用于设置箭头样式,facecolor= 设置颜色,width= 设置箭尾宽度,headwidth= 设置箭头宽度。在箭头绘制的过程中,还有一个 arrowstyle= 用于改变箭头的样式。另外,connectionstyle= 的参数可以用于更改箭头连接的样式。下图展示了常见的箭头连接样式。

综合案例

Paste_Image.png
import numpy as np
import matplotlib.pyplot as plt
ax = plt.subplot(111)
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))
X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
C, S = np.cos(X), np.sin(X)
plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-", label="Cos Function")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-", label="Sin Function")
#设置x,y轴范围
plt.xlim(X.min() * 1.1, X.max() * 1.1)
plt.ylim(C.min() * 1.1, C.max() * 1.1)
#设置x,y轴的坐标刻度
plt.xticks([-np.pi, -np.pi / 2, 0, np.pi / 2, np.pi],
           [r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])
plt.yticks([-1, +1],
           [r'$-1$', r'$+1$'])
t = 2 * np.pi / 3
plt.plot([t, t], [0, np.cos(t)],
         color='blue', linewidth=1.5, linestyle="--")
plt.scatter([t, ], [np.cos(t), ], 50, color='blue')
plt.annotate(r'$\sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$',
             xy=(t, np.sin(t)), xycoords='data',
             xytext=(+10, +30), textcoords='offset points', fontsize=16,
             arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
plt.plot([t, t], [0, np.sin(t)],
         color='red', linewidth=1.5, linestyle="--")
plt.scatter([t, ], [np.sin(t), ], 50, color='red')
plt.annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$',
             xy=(t, np.cos(t)), xycoords='data',
             xytext=(-90, -50), textcoords='offset points', fontsize=16,
             arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))

plt.legend(loc='upper left', frameon=False)
plt.show()
上一篇下一篇

猜你喜欢

热点阅读