Matplotlib
Matplotlib是python的一个非常基础的可视化工具,在此记录一下使用它的基础方法
1 基础部分
1.1 导包
import matplotlib.pyplot as plt
默认别名为plt
1.2 figure和axes
figure相当于是一张画布,在画图之前首先要生成一个figure才能在上边作画
axes是画图是需要用到的轴,不过这里默认会有四个轴
# 效果演示代码
import matplotlib.pyplot as plt
figure = plt.figure()
axes = plt.gca()
plt.show()
效果如下:
如上图所示,轴会有四条,轴上的刻度是默认添加的,可以修改。
由于平时经常用到的是左边和下边的轴,所以可以考虑把另外两条隐藏掉
# 隐藏上、右两条轴演示代码
import matplotlib.pyplot as plt
figure = plt.figure()
axes = plt.gca()
axes.spines['right'].set_color('none')
axes.spines['top'].set_color('none')
plt.show()
效果如下:
1.3 同时获取figure和axes,并在一张figure上画多张图
这里需要用的是plt.subplots()函数,该函数的返回值是figure和axes,即以下两种写法是等价的
figure = plt.figure()
axes = plt.gca()
# 等价于以下写法:
figure, axes = plt.subplots()
而且subplots函数可以传入nrows和ncols两个参数,可以在一张figure上画多个图
# 多个图演示代码
import matplotlib.pyplot as plt
# 设置两行两列,即四个图
figure, axes = plt.subplots(nrows=2, ncols=2)
# 把第一个图的上、右两轴取消掉
axes[0,0].spines['right'].set_color('none')
axes[0,0].spines['top'].set_color('none')
plt.show()
效果如下:
在这个代码中,获取的axes相当于是一个二维数组,其中每个元素代表每个图的坐标轴。
要获取指定图的坐标轴,与普通的获取二维数组元素的方式一样。
2 画图
2.1 柱状图
# 柱状图样例代码
import matplotlib.pyplot as plt
figure, axes = plt.subplots()
axes.spines['right'].set_color('none')
axes.spines['top'].set_color('none')
# x和y分别是横坐标和纵坐标的列表
x = [1, 2, 3, 4, 5]
y = [100, 200, 300, 250, 320]
# 画柱状图,设置宽度为0.5,透明度为0.4,颜色为橘色
plt.bar(x, y, width=0.5, alpha=0.4, color='orange')
plt.show()
效果如下:
plt.bar()函数是有返回值的,是一个数组,里边的元素分别代表一个柱形,可以单独对它们进行设置
柱状图也可以设置为横向的,有需要的话可以查一下方法
2.2 散点图
# 散点图样例代码
import matplotlib.pyplot as plt
figure, axes = plt.subplots()
axes.spines['right'].set_color('none')
axes.spines['top'].set_color('none')
# 横坐标和纵坐标列表
x = [1, 2, 3, 4, 5]
y = [100, 200, 300, 250, 320]
# 画散点图,设置散点大小为20,颜色为橘色
plt.scatter(x, y, s=20, color='orange')
plt.show()
效果如下:
2.3 折线图
# 折线图样例代码
import matplotlib.pyplot as plt
figure, axes = plt.subplots()
axes.spines['right'].set_color('none')
axes.spines['top'].set_color('none')
# 横坐标和纵坐标列表
x = [1, 2, 3, 4, 5]
y = [100, 200, 300, 250, 320]
# 画折线图,设置线的宽度为2,颜色为橘色
plt.plot(x, y, linewidth=2, color='orange')
plt.show()
效果如下:
另外,如果需要设置折线的样式,可以修改参数linestyle
2.4 饼状图
# 饼状图样例代码
import matplotlib.pyplot as plt
figure, axes = plt.subplots()
axes.spines['right'].set_color('none')
axes.spines['top'].set_color('none')
labels = ['A', 'B', 'C', 'D', 'E']
sizes = [100, 200, 300, 250, 320]
# 画饼状图,饼状图会根据sizes的比例自动生成,labels是各个扇形的名称,autopct设置格式化显示比例
plt.pie(sizes, labels=labels, autopct='%1.2f%%')
plt.show()
效果如下:
常用的图就这几种,后续如果有用到别的,会再更新
3 其他
3.1 保存图像
# 保存生成的图像,第一个参数设置路径和图像名,format设置图像格式
plt.savefig('./test.png', format='png',)
**注意:**保存图像一定要在plt.show()函数之前,plt.show()会把画布清空,如果在其之后保存图像,则只能保存一张白纸
3.2 坐标轴设置
上边案例中的坐标轴的坐标范围和刻度点都是函数根据给定值自动生成的,如果需要手动设置坐标范围或者改变刻度点的名称,可以使用以下方法:
# 设置坐标轴样例代码
import matplotlib.pyplot as plt
figure, axes = plt.subplots()
axes.spines['right'].set_color('none')
axes.spines['top'].set_color('none')
# 横坐标和纵坐标列表
x = [1, 2, 3, 4, 5]
y = [100, 200, 300, 250, 320]
# 画折线图,设置线的宽度为2,颜色为橘色
plt.plot(x, y, linewidth=2, color='orange')
# 设置横坐标刻度和刻度点的名称
x_ticks = [1, 2, 3, 4, 5]
x_grep_labels = ['A', 'B', 'C', 'D', 'E']
plt.xticks(x_ticks, x_grep_labels)
# 设置纵坐标刻度和刻度点名称
y_ticks = [100, 200, 400, 500]
y_grep_labels = ['0.1K', '0.2K', '0.4K', '0.5K']
plt.yticks(y_ticks, y_grep_labels)
# 设置坐标轴的名称
plt.xlabel('x_name')
plt.ylabel('y_name')
plt.savefig('test.png')
plt.show()
效果如下:
从上图中我们可以发现横纵坐标都有了名字,纵坐标的刻度范围变成了500,且横纵坐标的刻度点名称都变为了我们自己设置好的名称
3.3 索引值转不同颜色
之前画图时有这样一个需求:需要画很多不同的折线,每条折线需要用不同颜色标识出来,所以找到了一种可以根据不同索引值返回对应RGB颜色的方法:
import matplotlib.pyplot as plt
import matplotlib.cm as cmx
import matplotlib.colors as colors
def get_cmap(n):
# 返回一个可以根据索引值确定不同RGB颜色的函数
color_norm = colors.Normalize(vmin=0, vmax=n-1)
scalar_map = cmx.ScalarMappable(norm=color_norm, cmap='hsv')
def map_index_to_rgb_color(index):
return scalar_map.to_rgba(index)
return map_index_to_rgb_color
def main():
# 测试一下效果
N = 25
fig = plt.figure()
ax = fig.add_subplot(111)
plt.axis('scaled')
ax.set_xlim([ 0, N])
ax.set_ylim([-0.5, 0.5])
cmp = get_cmap(N)
for i in range(N):
col = cmp(i)
rect = plt.Rectangle((i, -0.5), 1, 1, facecolor=col)
ax.add_artist(rect)
ax.set_yticks([])
plt.show()
if __name__ == '__main__':
main()
效果如下: