plt常用绘图方法总结
Python里绘图一般都是matplotlib,有时候为了达到更好的效果或更方便绘图,会配合试用seaborn,其实际是对matplotlib的再一次封装。
一、通过折线图总结基本绘图参数设置
1、基本样式设置
以一个简单的折线图为例
import matplotlib.pyplot as plt
# 如果不指定x,默认从0开始的自然数序列
x = [1, 2, 3, 4]
y = [2, 4, 8, 16]
plt.plot(x, y)
plt.show()
从开发者角度讲,很多时候画出这个趋势图就以足够。但如果要对外提供图片素材,上图显然很不友好。因此,我们需要增加坐标含义、标题等说明性文本。(注意中文不能直接显示,需要设置字体,完整代码如下)
# 解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.xlabel('时间')
plt.ylabel('细菌数量')
plt.title('细菌繁殖速度图')
plt.plot(x, y)
plt.show()
如果我们要在一张图里绘制多个对象,往往还需要设置图例含义、线条颜色、类型、粗细等
x = [1, 2, 3, 4]
y = [2, 4, 8, 16]
y2 = [4, 16, 64, 256]
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.xlabel('时间')
plt.ylabel('细菌数量')
plt.title('细菌繁殖速度图')
plt.plot(x, y, '--', label='细菌1生长曲线', color='blue', linewidth=3.0)
plt.plot(x, y2, '-.', label='细菌2生长曲线', color='yellow')
plt.legend()
plt.show()
和折线图类似,其他图形的绘制也基本都有上述参数可以设置。不同的地方,将在下面展示
2、其他样式设置
(1)负数前的负号乱码问题
plt.rcParams['axes.unicode_minus'] = False
(2)画辅助网格线
# 设置网格线样式和透明度
plt.grid(ls="--", alpha=0.5)
(3)设置显示范围
# 设置x,y显示范围[x_min, x_max, y_min, y_max]
plt.axis([1, 4, 2, 100])
(4)设置图例名称位置
y = [2, 4, 8, 16]
plt.plot(y, label='图例1')
# 指定位置
plt.legend(loc='upper right')
plt.show()
可选参数如下
upper left | upper center | upper right |
center left | center | center right |
lower left | lower center | lower right |
(5)设置画布大小
我们所有的绘制都是在画布上的。实际上,上述代码使用的是默认画布大小。如果我们想指定画布大小,应该在绘制一开始指定参数
plt.figure(figsize=(12, 8))
(6)清空画布
有时候我们可能并不希望将多个对象都画在一张图里,就需要每次在绘制新图前清空画布
plt.clf()
(7)保存图片
plt.savefig('xxx.png')
(8)时序数据绘制
时序数据绘制的重点在于时间格式标准化,可以调用datetime、time等模块相应方法。具体可参考
Python时间模块(datetime)_Jiangugu的博客-CSDN博客
这里以更常见的表格读取场景为例
df = pd.read_excel('data.xlsx', parse_dates=['时间'], index_col='时间')
plt.plot(df.index, df['A'])
plt.show()
3、多图绘制
(1)标准的写法如下
# 创建一个2行2列共4个子图位置的画布,ax为数组,内容是子图对象
fig, ax = plt.subplots(2, 2)
# fig是画布,设置子图间距,防止重叠
fig.set_tight_layout(0.9)
sub1 = ax[0][0]
sub1.plot(y, color='blue')
sub1.set_xlabel('时间')
sub1.set_ylabel('细菌数量')
sub1.set_title('细菌1繁殖速度图')
sub2 = ax[1][1]
sub2.plot(y2, color='yellow')
sub2.set_xlabel('时间')
sub2.set_ylabel('细菌数量')
sub2.set_title('细菌2繁殖速度图')
plt.legend()
plt.show()
(2)其他快捷绘制方式
plt.tight_layout(pad=0.8)
# 2*2子图,绘制第1个
plt.subplot(2, 2, 1)
plt.plot(x, y, '--', label='细菌1生长曲线', color='blue')
plt.xlabel('时间')
plt.ylabel('数量')
plt.legend()
# 绘制第4个
plt.subplot(2, 2, 4)
plt.plot(x, y2, '-.', label='细菌2生长曲线', color='yellow')
plt.xlabel('时间')
plt.ylabel('数量')
plt.legend()
还可以通过如下方式绘制子图,方法和上面差别不大
fig = plt.figure()
sub1 = fig.add_subplot(2, 2, 1)
sub1.plot(y)
二、其他图形绘制
1、散点图
# 散点是二维的,必须指定x,y;后面参数分别指定颜色、形状、透明度、图例名、点大小
plt.scatter(x, y, c='b', marker='.', alpha=0.6, label='系列1', linewidths=3)
plt.scatter(x, y2, c='y', marker='*', alpha=0.9, label='系列2', linewidths=3)
plt.legend()
plt.show()
2、柱形图
(1)基本绘制
x = ['苹果', '香蕉', '香梨']
y1 = [3.5, 5.8, 3]
plt.title('水果销量统计')
plt.bar(x, y1, width=0.5, align='center')
plt.ylabel('重量(吨)')
plt.show()
(2)指定颜色
给每个柱子不同颜色,方法1是通过代表颜色的字符串一一指定
# 三个柱子分别指定颜色为红、绿、蓝
plt.barh(x, y1, align='center', color='rgb')
当柱子数目较多或提前未知时,可以通过colormap
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm as cmp
def my_norm(lst):
mx = np.max(lst)
mi = np.min(lst)
return list(map(lambda x: (x-mi)/(mx - mi), lst))
x = list('abcdefgh')
y1 = [3.5, 5.8, 3, 4, 5, 4.6, 7.8, 12]
norm_values = my_norm(y1)
# 选择一个色系,具体可选参数请看官网文档
map_vir = cmp.get_cmap(name='cool')
# 不同y值映射到色系上不同颜色,一般为了更好显示效果,会对y值做一定处理(如归一化)再去映射
colors = map_vir(norm_values)
plt.barh(x, y1, color=colors)
plt.show()
(3)同一刻度位置绘制多个柱形图
我们上面绘制的柱形图都是一个柱子对应一个坐标刻度,如果我们想绘制下面的效果
这个图实际上是分多次绘制的,本质在于计算每个柱形图x位置(设置合理宽度)
# 设置每个柱子宽度
width = 0.2
fruits = ['苹果', '香蕉', '香梨']
# [0, 1, 2]
x = np.arange(len(fruits))
x_spring = x
x_summer = x + width
x_autumn = x + 2 * width
x_winter = x + 3 * width
# 每个季度分别的销量
y1 = [3.5, 5.8, 3]
y2 = [4, 5, 4.5]
y3 = [7.8, 12, 9]
y4 = [4.5, 4.6, 4]
plt.bar(x_spring, y1, width=width, color='lime', label='春季')
plt.bar(x_summer, y2, width=width, color='red', label='夏季')
plt.bar(x_autumn, y3, width=width, color='yellow', label='秋季')
plt.bar(x_winter, y4, width=width, color='slategrey', label='冬季')
# 在对应的x刻度上添加文本标签
plt.xticks(x+width, labels=fruits)
# 标注每个柱形图的值
for i in range(len(fruits)):
# 写一个示例就行,参数分别是文本所在x y位置、内容
plt.text(x_spring[i], y1[i], y1[i], fontsize=8)
plt.legend()
plt.show()
(4)堆叠柱形图
这个的实质是计算y方向起始位置,不指定都从0开始。
plt.title('各收入群体占比')
plt.bar(0, 7, label='低收入')
plt.bar(0, 2, label='中等收入', bottom=7)
plt.bar(0, 1, label='高收入', bottom=7+2)
plt.ylabel('群体比例')
plt.legend()
plt.show()
3、饼图
labels = ["苹果", "香蕉", "香梨", "橘子", "西瓜"]
sizes = [120, 110, 80, 75, 180]
# 某一个区域的剥离,一般作强调突出
explode = (0, 0, 0, 0, 0.1)
plt.title("各主要水果销量统计")
# 设置百分比精度、是否有阴影、起始角度
plt.pie(sizes, explode=explode, labels=labels, autopct='%.2f%%', shadow=True, startangle=0)
plt.legend()
plt.show()
4、热力图
经常用于展示不同变量之间的相关性,不同颜色表示不同的相关性程度
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 设置显示字体大小
sns.set_context(font_scale=1.5)
df = pd.read_excel("data.xlsx")
sns.heatmap(df.corr(), vmin=-1, vmax=1, cmap=sns.color_palette('RdBu', n_colors=128))
plt.show()
5、箱线图
箱线图一般用于展示一组数据整体分布情况,直观展示数据范围、上下四分位数和均值,以及异常值。
# 0-1随机数100个
A = np.random.random(100)
# 基于正态分布,均值0,标准差1
B = np.random.normal(0, 1, 100)
plt.title("箱线图")
plt.boxplot((A, B), labels=["A", "B"])
plt.show()