在进入正文之前,先简单碎语几句。
如何做可视化,真的是一门大学问,要考虑色彩、展示样式、展示位置、目标群体、信息情况等等因素。作为小白的自己,对于这些高大上的使用场景,姑且先搁置一边,先扎扎实实的了解下如何做出一些基本的图表,然后在提升如何将自己的图表做个更美、更符合业务场景。而关于如何实现可视化,各工具的官网,无疑是最好的平台1。
碎语结束,切入正题!
如果对matplotlib的图表的基本组成元素尚不太清晰的你,在看下文之前,可以先查看一下博主之前整理的另一篇博文2 【归纳整理:图表的基本组成元素对应的matplotlib库中的方法】,作一下了解,可能方便你更好的理解下文的信息。
折线图 | 柱形图 | 条形图 | 散点图 | 气泡图 |
饼图 | 圆环图 | 雷达图 | 箱型图 | 热力图 |
水平线和垂直线 | 面积图 | 树地图 |
在正式查看matplotlib对基本图表的绘制之前,我们先对需要的库、环境、数据进行准备,具体如下代码中所示:
# 导入库及相关辅助代码
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"]="SimHei" # 解决中文乱码问题
plt.rcParams["axes.unicode_minus"]=False # 解决负号无法正常显示的问题
mpl.style.use('ggplot') # 设置画图风格
%matplotlib inline # 让图表直接在Jupyter Notebook中展示出来
# 在默认设置下 matplotlib 做出来的图表不是很清晰,将图表设置成矢量图格式显示,这样看起来会更清晰
# %config InlineBackend.figure_format='svg'
# 模拟数据
x = ['2017/10/1','2017/10/2','2017/10/3','2017/10/4','2017/10/5',
'2017/10/6','2017/10/7','2017/10/8','2017/10/9','2017/10/10']
y = [399,126,76,59,60,59,80,801,940,807]
y2 = [763,345,249,182,165,332,299,1297,2325,1779]
x2 = ['北京','上海','天津','重庆','深圳','广州','沈阳','云南','西藏','浙江']
x3 = np.arange(10)
colors = ['steelblue','#1111ff','indianred','green','red','yellow','orange','gray','#888222']
【备注】:下方的所有图表的示例数据,均用的上述代码中展示的样例数据,因此会有一些图的展示,不符合业务逻辑,请忽略其展示所代表的含义,这里我们关注的是可视化的实现手段。
常用于表示随着时间的推移某指标的变化趋势3。
plt.plot(x, y, color, linestyle, linewidth, marker, markeredgecolor, markeredgwidth, markerfacecolor, markersize, label)
参数说明:
x:x轴数据。
y:y轴数据。
linestyle:线条类型。
linewidth:线条宽度。
color:颜色。
marker:可以为线图添加散点,该参数指定点的形状。
markersize:指定点的大小。
markeredgecolor:指定点的边框色。
label:图例标签
alpha: 设置透明度
# 绘制单条折线图
plt.figure(figsize=(8,6))
plt.plot(x, # x轴数据
y, # y轴数据
linestyle = '-', # 折线类型
linewidth = 2, # 折线宽度
color = 'steelblue', # 折线颜色
marker = 'o', # 折线图中添加圆点
markersize = 6, # 点的大小
markeredgecolor='black', # 点的边框色
markerfacecolor='brown') # 点的填充色
for tx,ty in zip(x,y) : # 添加数据标签
plt.text(tx,ty,ty,ha='center',va='bottom',fontsize=12)
plt.ylabel('数量') # 添加y轴标签
plt.title('图例标题') # 添加图形标题
plt.grid(True) # 设置网格线
plt.savefig("plot.jpg") # 图表保存在本地
# 显示图形
plt.show()
其实在同一个坐标系中,绘制多条线,无非就是在不变动坐标系的情况下,不断的绘制而已。扩展一下的话,也就可以在同一个坐标系中绘制不同类型的图表,即图表的叠加。
回到正题,上面的图表下面的日期有点太过于紧凑,想针对于此进行特殊的设置,如下示例就可以根据实际的需求,实现自己的一些个性化需要。
# 绘制两条折线图
fig = plt.figure(figsize=(8,6))
ax = fig.add_subplot(1,1,1) # 熟悉一下add_subplot()
plt.plot(x, # x轴数据
y, # y轴数据
linestyle = '-', # 折线类型
label='count')
plt.plot(x,y2,label='tim')
plt.ylabel('数量') # 添加y轴标签
plt.title('图例标题') # 添加图形标题
plt.legend(ncol=2) # 显示图例
ax = plt.gca()# 获取图的坐标信息
date_format = mpl.dates.DateFormatter("%m-%d") # 设置日期的显示格式
ax.xaxis.set_major_formatter(date_format)
# xlocator = mpl.ticker.LinearLocator(10) # 设置x轴显示多少个日期刻度
xlocator = mpl.ticker.MultipleLocator(2) # 设置x轴每个刻度的间隔天数
ax.xaxis.set_major_locator(xlocator)
plt.xticks(rotation=45)# 为了避免x轴刻度标签的紧凑,将刻度标签旋转45度
# 显示图形
plt.show()
常用于比较不同类别之间的数据情况。
plt.bar(x, height, width=0.8, bottom=None, align=‘center’, color, edgecolor)
参数说明:
x:表示在什么位置显示柱子;
height:表示每根柱子的高度;
width:每根柱子的宽度,可以一样,也可以不一样;
bottom:表示每根柱子的底部位置,主要用在堆叠柱状图;
align:表示柱子和x值的位置关系,可选参数center/edge;
color:柱子的颜色;
edgecolor:柱子边缘的颜色
之后的示例其他诸如标签、标题、网格等信息的显示设置,都是通用的,之后的实例就不一一展开了,尽量使我们的**信息干货满满,而篇幅简短**。
plt.subplot(111) # 建立一个坐标系
# 绘制柱形图
plt.bar(x2,y,width=0.5, align="center", label="计划")
plt.show()
簇状柱形图,也有称分组柱形图,常用来表示不同类别随着同一变量的变化情况。
当绘制簇状柱形图的时候,需要调整柱子的显示位置,因此,其横坐标就不能像普通柱形图那样比较随意,可以是很多种格式的数据。簇状柱形图则需要其为数值型,从而方便调整柱子位置。
千言万语,不如一例一图见真照。上示例上图。
# 簇状柱形图
plt.subplot(111) # 建立一个坐标系
plt.bar(x3,y,width=0.4,color="green",label="计划")
plt.bar(x3+0.3,y2, width=0.4,color="red",label="实际")
plt.xticks(x3+0.15,x2) # 设置x轴的刻度
plt.legend()
plt.show()
堆积柱形图常用来比较同类别各变量和不同类别变量的总和差异。
绘制堆积柱形图,此时bar()函数的参数bottom就可以发挥功用了。通过指定bottom的底部位置,从而再次基础上进行再绘制,即得到堆积柱形图。具体看下示例。
# 堆积柱形图
plt.subplot(111) # 建立一个坐标系
# 绘制柱状图
plt.bar(x2,y,color="green",label="计划")
plt.bar(x2,y2, bottom=y,color="red",label="实际")
plt.legend()
plt.show()
条形图与柱形图类似,只不过是将柱形图的x轴和y轴进行了调换,柱形图就变成了我们所说的条形图。那对于参数的变化,个人觉得主要是参数width和height信息互换的变化,bottom参数变为left参数的变化。具体我们看下述的三个示例和上文的三个示例即可通晓。
plt.barh(y, width, height, align, color, edgecolor)
将柱形图示例中,width变为了height。
plt.subplot(111) # 建立一个坐标系
# 绘制条形图
plt.barh(x2,y,height=0.5, align="center", label="计划")
plt.show()
将簇状柱形图示例中,width变为了height。
# 簇状条形图
plt.subplot(111) # 建立一个坐标系
plt.barh(x3,y,height=0.4,color="green",label="计划")
plt.barh(x3+0.3,y2, height=0.4,color="red",label="实际")
plt.yticks(x3+0.15,x2) # 设置x轴的刻度
plt.legend()
plt.show()
将堆积柱形图示例中,bottom变为了left。
# 堆积条形图
plt.subplot(111) # 建立一个坐标系
# 绘制柱状图
plt.barh(x2,y,color="green",label="计划")
plt.barh(x2,y2 ,left=y,color="red",label="实际")
plt.legend()
plt.show()
散点图常用来发现两个数值变量之间的关系。
plt.scatter(x, y, s, c, marker, linewidths, edgecolors)
参数说明:
s:表示每个点的面积,即散点的大小。主要用在绘制气泡图时;
c:表示每个点的颜色;
marker:表示每个点的标记;
linewidths:表示每个散点的线宽;
edgecolors:表示每个散点外轮廓的颜色。
# 散点图
plt.subplot(111)
plt.scatter(y,y2,color = 'steelblue') # 指定散点图中点的颜色
plt.show()
气泡图本质上与散点图类似,让散点图中各点的大小不一,即得到气泡图。
# 气泡图
plt.subplot(111)
plt.scatter(y,y2,s=y2,c=y,alpha=0.5) # 指定散点图中点的颜色
plt.show()
饼图常用来表示同一等级中不同类别的占比情况。
plt.pie(x, explode, labels, colors, autopct, pctdistance, shadow,labeldistance,
startangle, radius, counterclock, wedgeprops, textprops, center, frame)
参数说明:
x:待绘图数据;
explode:饼图中每一块离圆心的距离;
labels:饼图中每一块的标签;
colors:饼图中每一块的颜色;
autopct:控制饼图中数值的百分比格式;
pctdistance:数据标签距中心的距离;
shadow:饼图是否有阴影;
labeldistance:每一块索引距离中心的距离;
startangle:饼图的初始角度;
radius:饼图的半径;
counterclock:是否让饼图逆时针显示;
wedgeprops:设置饼图内外边界的属性,如边界线的粗细、颜色等;
textprops:设置饼图中文本的属性,如字体大小、颜色等;
center:指定饼图的中心点位置,默认为原点;
frame:是否要显示饼图背后的图框,如果设置为True,则需要同时控制图框x轴、y轴的范围和饼图的中心位置。
# 饼图
plt.figure(figsize=(10,8))
plt.subplot(111)
explode=[0.5,0,0,0,0,0,0,0,0,0]#让第一块离圆心远一点
plt.pie(y, labels=x2, autopct='%.0f%%', explode=explode,shadow=True)
plt.show()
圆环图是与饼图类似的一种图表,常用来表示同一层级不同类别之间的占比关系,如示例二。或者就是表示同一等级中不同类别的占比情况,为了可视化效果,如示例一。
在饼图的基础上调整wedgeprops参数即可实现圆环图。
具体如下示例:
# 示例一:圆环图
plt.figure(figsize=(10,8))
plt.subplot(111)
plt.pie(y, labels=x2, autopct='%.0f%%',wedgeprops=dict(width=0.6, edgecolor='w'))
plt.show()
# 示例二:圆环图
plt.figure(figsize=(10,8))
plt.subplot(111)
plt.pie(y, wedgeprops=dict(width=0.2, edgecolor='w'))
plt.pie(y, radius=0.7, wedgeprops=dict(width=0.2, edgecolor='w'))
#添加注释
plt.annotate("计划", xy = (0.35,0.35), xytext = (0.7,0.45),
arrowprops=dict(facecolor='black', arrowstyle ='->'))
plt.annotate("实际", xy = (0.75,0.35), xytext = (0.3,0.45),
arrowprops=dict(facecolor='black', arrowstyle ='->'))
plt.show()
雷达图常用来综合评价某一事物,它可以直观地看出该事物的优势与不足。
雷达图使用的是plt库中的polar方法,polar是用来建立极坐标系的,其实雷达图就是先将各点展示在极坐标系中,然后用线将各点连接起来。
plt.polar(theta, r, color, marker, linewidth)
参数说明:
theta:每一点在极坐标系中的角度;
r:每一点在极坐标系中的半径;
color:连接各点之间线的颜色;
marker:每点的标记形状;
linewidth:连接线的宽度。
备注:忽略我们图中数据表示的意义,只是为了尽量让我们的示例数据,可以在整篇文中通用而已。此刻,我们只关注实现方法。
# 雷达图
plt.subplot(111,polar=True)# 建立极坐标系
# 在指定的间隔数内返回均匀间隔的角度数字
angles = np.linspace(0,2*np.pi,len(y),endpoint=False)
# 数据闭合处理
data = np.concatenate((y, [y[0]]))
labels = np.concatenate((x2, [x2[0]]))
angles =np.concatenate((angles, [angles[0]]))
plt.polar(angles,data,color="red",marker="o")
plt.xticks(angles,labels)
plt.show()
箱形图用来反映一组数据的离散情况(分布情况)。
plt.boxplot(x, notch=None, sym=None, vert=None, whis=None, positions=None, widths=None, patch_artist=None, bootstrap=None, usermedians=None, conf_intervals=None, meanline=None, showmeans=None, showcaps=None, showbox=None, showfliers=None, boxprops=None, labels=None, flierprops=None, medianprops=None, meanprops=None, capprops=None, whiskerprops=None, manage_ticks=True, autorange=False, zorder=None, *, data=None)
参数说明:
x:绘图数据。
notch:是否以凹口的形式展现箱线图,默认非凹口。
sym:指定异常点的形状,默认为+号显示。
vert:是否需要将箱线图垂直摆放,默认垂直摆放。
whis:指定上下须与上下四分位的距离,默认为1.5倍的四分位差。
positions:指定箱线图位置,默认为[0,1,2…]。
widths:指定箱线图宽度,默认为0.5。
patch_artist:是否填充箱体的颜色。
meanline:是否用线的形式表示均值,默认用点表示。
showmeans:是否显示均值,默认不显示。
showcaps:是否显示箱线图顶端和末端的两条线,默认显示。
showbox:是否显示箱线图的箱体,默认显示。
showfliers:是否显示异常值,默认显示。
boxprops:设置箱体的属性,如边框色、填充色等。
labels:为箱线图添加标签,类似于图例的作用。
filerprops:设置异常值的属性,如异常点的形状、大小、填充色等。
medianprops:设置中位数的属性,如线的类型、粗细等。
meanprops:设置均值的属性,如点的大小、颜色等。
capprops:设置箱线图顶端和末端线条的属性,如颜色、粗细等。
whiskerprops:设置须的属性,如颜色、粗细、线的类型等。
# 箱型图
plt.subplot(111)
data = [y,y2]
labels = ['计划','实际']
plt.boxplot(data,labels=labels,vert=True,widths=[0.2,0.4],
patch_artist=True,showmeans=True,
boxprops = {'color':'black', 'facecolor':'steelblue'},
flierprops = {'marker':'o','markerfacecolor':'red', 'markersize':3},
meanprops = {'marker':'D','markerfacecolor':'indianred', 'markersize':4},
medianprops = {'linestyle':'--','color':'orange'})
plt.show()
热力图是将某一事物的响应度反映在图表上,可以快速发现需重点关注的区域。
plt.imshow(x, cmap)
参数说明:
x:表示待绘图的数据,需要是矩阵形式;
cmap:配色方案,用来表明图表渐变的主题色。
cmap的所有可选值都封装在plt.cm里,在Jupyter Notebook中输入**plt.cm.**,然后按Tab键就可以看到。
# 热力图
data = np.array([y,y2,y,y2])
cmap=plt.cm.cool#设置配色方案
plt.imshow(data, cmap = cmap)
plt.colorbar()#显示右边的颜色条
plt.grid(False)#关闭网格线
#将数值显示在指定位置
for i in range(data.shape[0]):
for j in range(data.shape[1]):
plt.text(j, i, data[i, j], horizontalalignment="center")
plt.show()
水平线和垂直线主要用来做对比参考。
plt.axhline(y, xmin, xmax)
plt.axvline(x, ymin, ymax)
参数说明:
y/x:画水平/垂直线时的横/纵坐标;
xmin/xmax:水平线的起点和终点;
ymin/ymax:垂直线的起点和终点;
# 水平线
plt.subplot(121)
plt.axhline(y=2,xmin=0.2,xmax=0.9)
# 垂直线
plt.subplot(122)
plt.axvline(x=2,ymin=0.2,ymax=0.9)
plt.show()
面积图是与折线图类似的一种图形,主要是对线下的部分进行了填充。
plt.stackplot(x, y, labels, colors)
参数说明:
x/y:坐标数值;
labels:不同系列图表的图例名;
colors:不同系列图表的颜色。
# 面积图
plt.subplot(111)
plt.stackplot(x, y, y2, labels=['计划','实际'])
plt.legend(ncol=2)
plt.show()
树地图也是一种用来表示同一等级中不同类别的占比关系。树地图可以利用矩形的面积来表示其数值大小,即面积越大,其值越大。
树地图需要使用squarify库。安装方法很简单:
pip install squarify -i https://pypi.douban.com/simple
树地图方法:
import squarify
squarify.plot(sizes, label, color, value, edgecolor, linewidth)
参数说明:
sizes : 指定绘图数据
label : 指定不同类别图例标签
color : 指定不同类别的颜色
alpha : 指定透明度
value : 指定不同类别的数据标签
edgecolor : 指定类别之间边框的颜色
linewidth : 设置边框的宽度
# 树地图
import squarify
plt.subplot(111)
squarify.plot(sizes=y,label=x2,value=y2,color=colors,edgecolor='white')
plt.show()
https://matplotlib.org ↩︎
【归纳整理:图表的基本组成元素对应的matplotlib库中的方法】 ↩︎
《对比Excel,轻松学习Python数据分析》作者:张俊红 出版社:电子工业出版社 出版时间:2019年2月 ISBN:9787121357930 ↩︎