基本概念
数据可视化是指借助于图形化的手段,清晰、快捷有效的传达与沟通信息。同时,也可以辅助用户做出相应的判断,更好的去洞悉数据背后的价值
matplotlib
matplotlib是用于Python的绘图库,提供各种常用图形的绘制。例如,条形图,柱形图,线图,散点图等
根据惯例,使用如下的方式导入:
import matplotlib as mpl
import matplotlib.pyplot as plt
绘制线图
可以通过matplotlib.pyplot的plot方法进行图形绘制。
plt.plot([1,2],[3,4],"ro--",[5,6],[7,8],"g<-")
也可以分两次绘制,如下:
plt.plot([1,2],[3,4],"ro--")
plt.plot([5,6],[7,8],"g<-")
输出图形如下:
需要注意的是:如果x坐标未给定,则默认是0,1,2,3,4…
x,y两个数组,对位取元素,构成一个坐标,进行绘制。
画曲线。
x = np.linspace(0,2*np.pi,100)
y =np.sin(x)
plt.plot(x,y,"r")
图形交互式设置
我们可以设置jupyter notebook图形是否交互式显示,默认为否。
%matplotlib notebook
设置中文支持
matplotlib默认情况下不支持中文显示,如果需要显示中文,则我们需要做一些额外的设置操作。设置可以分为:
全局设置
局部设置
全局设置
我们可以通过执行:
mpl.rcParams["font.family"] = "中文字体名称"
mpl.rcParams["axes.unicode_minus"]=False
进行设置
常用的设置如下:
font.family 字体的名称
sans-serif 西文字体(默认)
SimHei 中文黑体
FangSong 中文仿宋
YouYuan 中文幼圆
STSong 华文宋体
Kaiti 中文楷体
LiSu 中文隶书
font.style 字体的风格
normal 常规(默认)
italic 斜体
oblique 倾斜
font.size 字体的大小(默认10)
axes.unicode_minus 是否使用Unicode的减号(负号)【在支持中文显示状态下,需要设置为False】,这是因为但是,字体设置成支持中文的字体后,负号(-)也会使用中文的负号,而中文的负号又不支持显示,
mpl.rcParams["font.family"]="YouYuan"
mpl.rcParams["axes.unicode_minus"]=False
mpl.rcParams["font.size"]=10
plt.plot([-1,-2,-3],[4,5,6])
plt.title("标题")
使用mpl.rcParams设置参数时,是一种全局的设置,我们也可以进行局部的设置,仅对当前的绘制生效。当全局设置与局部设置冲突时,以局部设置为准。
plt.plot([-1,-2,-3],[4,5,6])
plt.title("标题1",fontsize=20,fontproperties= "Kaiti")
输出:
保存图表
通过plt的savefig方法将当前的图形保存到硬盘或者类文件对象中,相关参数如下:
dpi:每英寸分辨率点数。
facecolor:设置图像的背景色。
bbox_inches:设置为tight,可以紧凑保存图像
x= np.linspace(0,2*np.pi,100)
y = np.sin(x)
plt.plot(x,y)
plt.savefig("e:/jupyter_notebook/test11.jpg",dpi=200,facecolor="#ff0000",bbox_inches="tight")
读取图形:
from PIL import Image
image = Image.open("e:/jupyter_notebook/test11.jpg")
image.show()
读取结果会用默认图片浏览器打开
保存图像。保存到类文件对象中。
from io import BytesIO
bio = BytesIO()
plt.savefig(bio)
bio.read()
bio.getvalue()
bio.seek(0)
bio.getvalue()
输出:
需要注意的是如果读取一遍后需要再次读取需要重新将指针设置为文件开头,否则无法读取
颜色,点标记与线型设置
我们可以在绘制图形时,显式指定图形的颜色,点标记或线条形状。具体设置可以查看帮助文档
color©:线条颜色。
linestyle(ls):线条形状
linewidth(lw):线宽。
marker:点标记形状
markersize(ms):点标记的大小
markeredgecolor(mec):点边缘颜色
markeredgewidth(mew):点边缘宽度
markerfacecolor(mfc):点的颜色。
说明:
颜色,点标记与线型可以使用一个参数进行设置
颜色除了可以使用预设简写的字符之外,也可以使用全称(例如red)也可以使用RGB颜色表示。
如下所示:
plt.plot([1, 2, 3], [4, 5, 6], c="g", ls="--", marker=">", ms=20)
plt.plot([1, 2, 3], [4, 5, 6], marker="o", mec="r", ms=15, mew=5, mfc="g")
plt.plot([1, 2, 3], [4, 5, 6], "o--r")
plt.plot([1, 2, 3], [4, 5, 6], c="green")
透明度设置
在绘制图像时,我们可以通过alpha参数来控制图像的透明度,值在0 ~ 1之间。0为完全透明,1为不透明。
如下所示:
plt.plot([1, 2, 3], [4, 5, 6], alpha=0.5)
图例设置
在绘制多条线时,可以设置图例来标注每条线所代表的含义,使图形更加清晰易懂。
可以采用如下的方式设置图例:
调用plt的legend函数,传递一个标签数组,指定每次plot图形的标签。
在绘制的时候通过label参数指定图例中显示的名称,然后调用legend函数生成图例。
legend常用的参数:
loc:指定图例的位置。默认为best。也可以指定坐标(元组),基于图像左下角计算。
frameon:设置是否含有边框。
title:设置图例的标题。
ncol:图例显示的列数,默认为1。
plt.plot(np.arange(1,13),np.random.randint(50,70,size=12),label = "2018年")
plt.plot(np.arange(1,13),np.random.randint(60,70,size=12),label = "2017年")
plt.legend()
plt.plot(np.arange(1,13),np.random.randint(50,70,size=12))
plt.plot(np.arange(1,13),np.random.randint(60,70,size=12))
plt.legend(["2018年","2017年"])
plt.plot(np.arange(1,13),np.random.randint(50,70,size=12),label = "2017年")
plt.plot(np.arange(1,13),np.random.randint(60,70,size=12),label = "2018年")
plt.legend(["2017年","2018年"])
输出:
loc 指定图例显示的位置。如果没有显式设置,会选择最合适的位置进行显示(默认值best或0)。
loc matplotlib中提供了几种显示位置,除此之外,也支持使用元组进行设置。元组指定基于图像尺寸偏移的比例。原点在左下角。设置图例是否显示边框,默认为True。
plt.plot(np.arange(1,13),np.random.randint(50,70,size=12),label = "2017年")
plt.plot(np.arange(1,13),np.random.randint(60,70,size=12),label = "2018年")
plt.legend(["2017年","2018年"],loc=(0.8,0.8),frameon=False)
plt.plot(np.arange(1,13),np.random.randint(50,70,size=12),label = "2017年")
plt.plot(np.arange(1,13),np.random.randint(60,70,size=12),label = "2018年")
plt.legend(["2017年","2018年"],title = "标题",ncol=2)
输出:
网格设置
可以通过plt的grid方法来设置是否显示网格。True为显示,False不显示。ax.grid(color=‘r’, linestyle=’-’, linewidth=2)
color:设置网格线颜色
axis:设置网格线显示x,y或者全部显示(x,y,both)。
linestyle:设置网格线形状。
linewidth:设置网格线宽度。
plt.plot([1,2,3],[4,5,6])
plt.grid(True,color = "r",axis ="x",linestyle = "--",linewidth=2)
输出:
绘图区域设置
我们可以在一张图上绘制多个图形,当然,我们也可以将不同的图形绘制到多个不同的区域当中
我们可以采用以下方式来实现多个区域的绘制(创建子绘图区域):
通过Figure对象调用add_subplot方法
通过plt的subplot方法
通过plt的subplots方法
子区域1:add_subplot方法
首先创建matplotlib.figure.Figure对象,然后通过Figure对象的add_subplot方法增加子绘图区域。
add_subplot方法中,需要指定子区域的行数、列数与当前要绘制的子区域。
add_subplot方法会返回子绘图对象(轴对象),通过该对象即可实现绘图(matplotlib.axes._subplots.AxesSubplot)。
在绘制图形时,总是需要创建Figure对象。如果没有显式创建,则plt会隐式创建一个Figure对象。在绘制图形时,既可以使用plt来绘制,也可以使用子绘图对象来绘制
如果使用plt对象绘制,则总是在最后创建的绘图区域上进行绘制,如果此时尚未创建绘图区域,则会自动创建。
说明:
add_subplot方法的参数,即可以使用三个参数分开传递,也可以使用一个参数整体传递。
可以通过plt.subplots_adjust方法来调整子绘图的位置与子绘图之间的距离。(left, right, top, bottom, wspace, hspace)
创建子区域时,可以使用facecolor设置绘图区域的背景色。
创建Figure对象(画图对象),我们要进行绘制图形,就必须要有该对象的支持。
如果我们没有显式创建该对象,则在调用plt.plot的时候,会自动创建。
通过绘图对象增加子绘图区域。add_subplot方法会返回子绘图区域对象。
参数: 第一个:行数 第二个:列数 第三个:当前子绘图区域的位置(索引从1开始)
f = plt.figure()
a = f.add_subplot(1,2,1)
a.plot([1,2,3],[4,4,5])
b = f.add_subplot(1,2,2)
b.plot([1,2,3],[7,8,9])
输出:
add_subplot也可以通过字符串的形式,进行传递参数。(将三个参数合并到一起)
调整子绘图区域之间或子绘图区域与画图之间空隙。
f = plt.figure()
a = f.add_subplot("121")
a.plot([1,2,3],[4,4,5])
b = f.add_subplot("122")
b.plot([1,2,3],[7,8,9])
plt.subplots_adjust(wspace=0.5,hspace=1)
输出:
在绘制图形时,我们可以通过调用自绘图区域对象plot方法绘制,也可以调用plt的plot进行绘制,当我们使用plt的plot进行绘图时,我们实际上是通过子绘图区域对象来绘制的。plt永远是绘制在最后一个创建的子绘图区域上。如果当前没有任何绘图区域,则会自动创建一个。
可以通过facecolor来指定子绘图区域的背景色。
f = plt.figure()
a = f.add_subplot("121")
a.plot([1,2,3],[4,4,5])
b = f.add_subplot("122",facecolor="r")
b.plot([1,2,3],[7,8,9])
输出:
子区域2:subplot方法
通过调用plt的subplot方法创建子绘图区域,该方法返回子绘图对象。此处方式下,会隐式创建Figure对象。
实际上,这种创建子绘图区域的方式,底层也是通过第一种方式实现的。
subplot会返回子绘图区域对象。
subplot在参数上与figure对象的add_subplot方法类似,支持3个参数,也支持1个str类型的参数。
a = plt.subplot(1,2,1)
a.plot([1,2,3],[4,5,6])
b = plt.subplot("122")
b.plot([2,3,4],[5,6,7])
输出:
子区域3:subplots方法
通过plt的subplots方法创建子绘图区域,该方法返回一个元组(Figure对象与所有子绘图对象,如果是多个子绘图对象,则返回一个ndarray数组)。可以通过sharex与sharey来指定是否共享x轴与y轴
plt.subplots 返回一个元组,元组中含有两个元素。第1个元素是绘图Figure对象,第2个元素是所有创建好的子绘图区域对象。
我们可以通过sharex与sharey设置是否共享x轴与y轴。默认为False。
figure,ax = plt.subplots(1,2,sharex =True,sharey=True)
display(figure,ax)
ax[0].plot([1,2,3],[4,5,6])
ax[1].plot([4,5,6],[1,2,3])
输出:
绘图区域大小设置
如果绘图子区域较多,可能会有些拥挤。此时,我们可以调整绘图区域的大小。方式如下:
在调用plt.figure()创建Figure对象时,通过figsize参数指定。单位为英寸
在创建Figure对象后,可以通过Figure对象的set_size_inches方法设置。
说明:
如果没有显式创建Figure对象,可以通过plt的gcf函数获取当前的Figure对象。
在创建figure对象时,可以通过figsize参数来指定画布的大小。(单位:英寸)
plt.figure((fsize=(3,3)))
也可以在创建figure对象之后,通过调用set_size_inches方法来进行设置。
f = plt.figure()
f.set_size_inches(3, 3)
plt.plot([1, 2, 3], [3, 4, 5])
如果没有显式的创建figure对象,我们可以通过plt.gcf获取当前的figure对象。
f = plt.gcf()
f.set_size_inches(4, 10)
plt.plot([1, 2, 3], [4, 5, 6])
标签与刻度设置
可以通过plt对象的相关方法来设置(或获取)标签与刻度等信息。设置还是获取,取决于是否传递实际参数。
plt.xlim 设置或获取x轴刻度范围。
plt.ylim 设置或获取y轴刻度范围。
plt.xticks 设置或获取x轴显示的刻度与标签。
plt.yticks 设置或获取y轴显示的刻度与标签。
plt.axis 可以同时设置或获取x与y轴的刻度范围,或者是取消刻度显示。
无参数:返回一个元组。(xmin, xmax, ymin, ymax),(xmin, xmax, ymin, ymax) 同时设置x与y轴的刻度范围。
off 取消坐标轴显示
tight:坐标轴紧凑显示。
equal:x与y具有同样的长度。
轴标签说明与标题设置
plt.xlabel 设置x轴的标签说明
plt.ylabel 设置y轴的标签说明
plt.title 设置标题。
xlim, ylim等方法,即可以进行设置,也可以获取。到底是设置还是获取,取决于我们调用方法时,是否传递参数,如果传递参数,则进行设置。如果没有传递参数,则进行获取。
plt.plot([3, 5, 7], [1, 5, 7])
t = plt.xlim()
display(t)
xmin, xmax = plt.xlim()
display(xmin, xmax)
设置x轴的最小值与最大值以及单独设置最大值最小值。
plt.xlim(0, 10)
plt.xlim(0)
plt.xlim(xmax=10)
在设置刻度值时,也可以同时设置对应刻度值显示的标签。
plt.xticks([20, 40, 60], ["弱冠", "不惑", "花甲"])
plt.axis((0, 8, -2, 10))
取消坐标轴的显示
plt.axis("off")
设置坐标轴紧凑显示。
plt.axis("tight")
令x与y轴等比例尺显示。
plt.axis("equal")
通过绘图对象设置标签与标题
除了通过plt对象外,我们还可以通过子绘图对象来设置与获取标签与刻度。
ax.set_xlim 设置x轴刻度范围。
ax.get_xlim 获取x轴刻度范围。
ax.set_xticks 设置x轴显示的刻度。
ax.get_xticks 获取x轴显示的刻度。
ax.set_xticklabels 设置x轴显示的刻度标签。默认显示的是就是刻度值。
ax.get_xticklabels 获取x轴显示的刻度标签。
也可以设置标签说明与标题。
ax.set_xlabel 设置x轴的标签说明。
ax.get_xlabel 获取x轴的标签说明。
ax.set_title 设置标题。
ax.get_title 获取标题
说明:
如果需要设置或者获取y轴,只需要将x换成y即可。
在设置标签时,可以使用rotation参数,令标签旋转。
figure, ax = plt.subplots(1, 1)
ax.set_xlim(5, 10)
# ax.get_xlim()
ax.set_xticks([5, 7, 9])
ax.set_xticklabels(["aasdfadsf", "basdfasdf", "casdfasdfad"], rotation=90 )
ax.set_xlabel("x轴")
ax.set_ylabel("y轴")
ax.set_title("标题信息")
添加注解
我们可以在图形上绘制文本等说明信息(注解)。
普通文本:
plt.text 显示文本(基于坐标)
plt.figtext 显示文本(基于图片)
箭头:
plt.arrow 根据起点坐标(x,y)与各自轴的长度(x + dx, y + dy)绘制箭头。
width 箭头尾部的宽度。
head_width 箭头的宽度。
head_length 箭头的长度
箭头与文本:
plt.annotate 显示箭头与文本
xy 箭头指向坐标
xytext 文本起点坐标。(箭头尾部坐标)
arrowprops 字典类型,可设置箭头的属性。
facecolor 箭头的颜色
headwidth 箭头的宽度
width 箭尾的宽度
shrink 收缩大小
headlength 箭头的长度
arrowstyle 一些预设的箭头样式。当含有该参数时,上述4项参数将不再有效。
x = np.linspace(-10, 10, 1000)
y = x ** 2
y2 = x * 2
plt.plot(x, y)
plt.plot(x, y2)
# 绘制文本说明信息。基于坐标。
# plt.text(0, 40, "$y=x^2$")
# plt.text(9, 0, "$y=x * 2$")
# 绘制文本说明信息。基于图像的比例。(原点在坐下角)
# plt.figtext(0.5, 0.8, "y=x*2")
x = np.linspace(-10, 10, 1000)
y = x ** 2
plt.plot(x, y)
# plt.text(0, 0, "这是极值点")
# 绘制箭头。前两个参数指定起始点的坐标。第3个参数指定x轴的偏移量,第4个参数指定y轴的偏移量。
# plt.arrow(-5, 40, 5, -40, width=0.5, head_width=0.8, head_length=1.5, color="r")
# plt.text(-5, 45, "这是极值点")
# plt.annotate(s="这是极值点", xy=(0, 0), xytext=(-5, 40), arrowprops=dict(width=2, facecolor="r", headwidth=10,
# headlength=10, shrink=0.1))
plt.annotate(s="这是极值点", xy=(0, 0), xytext=(-5, 40), arrowprops=dict(arrowstyle="->"))
我们可以通过plt.style.use(“样式名”)来设置绘图使用的样式。
说明: 执行plt.style.available来获取所有的绘图样式。
一、折线图
折线图适用于显示数据的趋势,增加变化的场景中。例如,气温的变量,销售的增加变化等。
plt.plot([1,2,3],[4,9,6])
输出:
二、柱形图 / 条形图
plt.bar 柱形图
plt.barh 条形图
柱形图/条形图适合于显示数据对比的场景之中
三、饼图
plt.pie 饼图
labels 每个部分显示的标签。
explode 指定每个部分距离圆心的偏移量(单位为半径的长度)。
colors 指定每个部分的颜色。
autopct 设置每个部分显示的比例值(格式化)。
couterclock 是否逆时针绘图。默认为True。
startangle 初始绘图点位置(逆时针偏移x轴的角度)。默认为偏移0度(x轴)。
shadow 是否含有阴影,默认为False。
饼图适合于显示数据的占用比例的场景。饼图显示比例的时候,数据量不宜过多。
plt.pie([1, 2, 3, 4], labels=["a", "b", "c", "d"], explode=[0, 0, 0, 0.5],
colors=["r", "g", "b", "#FFFF00"],
autopct="%.2f%%",counterclock=True,startangle=90,shadow=True)
输出:
四、散点图 / 气泡图
散点图适合于用来显示与比较数据的分布状态。
marker 点的标记。
s 点的大小。
color 点的颜色
说明:
color与s参数可以统一设置,也可以为每一个点单独设置。
散点图用来表示两个维度,当散点图的点显示不同大小时,就称为气泡图。气泡图可以显示2-4个维度。(气泡的大小,气泡的颜色)
color=["r", "g", "b", "y"]
plt.scatter(np.random.randint(0, 100, 100), np.random.randint(0, 100, 100),
np.random.randint(10, 100, 100), color=np.random.choice(color, 100))
五、直方图
直方图(histogram)可以看成是一种特殊的柱形图,用来将连续的数据频率(数量)进行离散化显示。在直方图中,数据被分割成若干区间,然后统计每个区间数据出现的频率(数量)。
我们可以通过plt.hist来绘制直方图。
bins:设置分割区间的数量。
normed:进行归一化显示。(概率密度)
直方图用来将连续的数据进行离散化的显示。hist方法返回两个数组。第一个数组返回每个区间数据的数量。
第2个数组返回每个区间的范围。每个区间的范围是前闭后开形式(包含起始点, 不包含终止点)
特殊:最后一个区间(桶),是双闭区间(包含起始点,也包含终止点)。
hist默认会分为10段(10个桶),我们也可以自定义桶的数量
plt.hist(x, bins=10)
当bins参数指定为整数时,则等分为bins值的桶数。我们也可以根据实际需要,进行不等的区间划分。
时,可以将bins参数设置一个数组类型,指定区间数值(区间边界)。
x = np.random.randint(1, 81, 1000)
plt.hist(x, [1, 10, 30, 80])
输出:
六、箱线图
箱线图也称盒须图。通过极值与Q1,Q2,Q3值来描述数据。通过箱线图,我们可以发现数据中的离群(异常)值。 箱线图的离群点定义为:Q3+1.5IQR和Q1-1.5IQR。其中IQR为两个四分位之间的距离。
plt.boxplot([1, 5, 8, 10, 2, 6, 9, 10, -20])
Series与DataFrame类型的对象也支持图形绘制,使用对象的plot方法即可。
如果我们需要绘制图形的数据就存在Series或者DataFrame对象中,我们就可以直接绘制,而无需使用plt.plot。
s = pd.Series([5, 2, 4, 6, 8, 9, 10])
s.plot(kind="density")
df = pd.DataFrame([[1, 3, 5], [2, 4, 6], [9, 8, 2], [6, 5, 8]])
df.plot(kind="bar", stacked=True)
df.plot.bar()
其他类型图形
line:线形图
bar:柱形图
barh:条形图
hist:直方图
kde / density:核密度图
pie:饼图
box:箱线图
area:面积图
参数:
color
alpha
stacked:是否堆叠。