Python数据处理之Matplotlib学习

王 茂南 2018年4月30日20:03:22
评论
1 28119字阅读93分43秒
摘要这一篇文章会介绍一下python数据分析中matplotlib的使用。把一些常用的方法记录在此,方便自己以后的查阅与学习。

Matploylib介绍

在数据分析的时候,我们经常需要将数据可视化,这是就需要使用matplotlib模块了。

我们首先将matplotlib.pyplot导入后命名为plt, 在后面的内容中,出现的plt都默认是matplotlib.pyplot

  1. import matplotlib.pyplot as plt
  2. %matplotlib inline

在使用 jupyter 的时候需要加上后面这句。

可视化的一些 Tips

  • 当数据相差比较大的时候,绘制图像的时候有一部分数据挤在一起,这个时候可以使用 Log 对数据先进行对数处理,接着在进行绘图;
  • 当坐标轴的数字比较大的时候,可以将其除一个数,使其变小,在 label 上进说明即可;

结合 pandas 进行绘图

这一部分内容可以参考自,Pandas 指南-Pandas 绘图说明

 

matplotlib基础

matplotlib是面向对象的绘图工具包,绘制的图形中每一个元素都是一个对象,比如线条,文字,刻度等信息,可以通过修改这些对象的属性,从而改变绘图样式。

matplotlib中主要的绘图对象列表如下:

  • Figure对象,可以想象为一张画布;
  • Axes对象,字面理解为坐标轴(因为每一个 Axes 都有一套 X Y轴坐标系,绘制图形时基于此坐标系绘制。) 也可以认为是子图,在一个Figure对象中可以包含多个Axes对象,也就是说一张画布可以包含多个子图;
  • Line2D对象,代表线条;
  • Text对象,代表了文字,比如一张子图需要标题,就可以使用一个Text对象;

下面我们先来看一个简单的例子:

  1. N = 50
  2. x = np.random.random(N) # 横坐标
  3. y = np.random.random(N) # 纵坐标
  4. colors = np.random.random(N) # 每个坐标的颜色
  5. area = np.pi*(10*np.random.random(N))**2 # 每个坐标的颜色
  6. plt.scatter(x,y,s=area,c=colors,alpha=0.5)
  7. plt.show()

我们可以看一下画出来的图像,是一个散点图

Python数据处理之Matplotlib学习

在上面这个例子中,我们没有创建任何Figure对象,这是因为plt会默认创建Figure对象并保存在plt内部。

下面我们通过plt.figure()创建一个新的Figure对象,然后在此Figure对象上创建Axies对象。

  1. fig = plt.figure()
  2. ax1 = fig.add_subplot(2,2,1) #添加一个Axes对象到布局为两行两列的第一个位置
  3. ax2 = fig.add_subplot(2,2,2)
  4. ax3 = fig.add_subplot(2,2,3)
  5. ax1.plot(np.random.randn(50).cumsum(), 'k--')
  6. ax2.hist(np.random.randn(100), bins=20, color='k')
  7. ax3.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30))
  8. fig.show()

我们首先创建一个Figure对象,接着插入三个Axes对象,接着在Axes对象上绘制累积和线图,直方图以及散点图。

我们要注意的是上面的fig.add_subplot(2,2,1)表示添加一个Axes对象到布局为两行两列的第一个位置。我们看一下上面代码绘制出图像的样子:

Python数据处理之Matplotlib学习

到这里我们就把 matplotlib 的基本功能看完了,下面我们看一下常用的属性设置。

 

子图的绘制

这里我们详细说明一下子图的绘制. matplotlib使用plt.subplots来绘制子图, 我们可以使用下面的命令绘制一个2行, 5列的子图. 这里可以通过循环的方式进行子图的绘制,同时通过 subplots_adjust 来控制子图之间的间距。

  1. fig, axs = plt.subplots(2, 5, figsize=(15, 6), facecolor='w', edgecolor='k')
  2. fig.subplots_adjust(hspace = .5, wspace=.001)
  3. axs = axs.ravel()
  4. for i in range(10):
  5.     axs[i].contourf(np.random.rand(10,10),5,cmap=plt.cm.Oranges)
  6.     axs[i].set_title(str(250+i))

如果我们希望子图中的坐标轴关闭,可以在循环中加入下面的语句:

  1. axs[i].axis("off")

 

子图共享坐标轴

有下面两种方式可以共享子图的坐标轴, 我们可以设置为全局共享, 及所有的子图都能共享坐标轴:

  1. fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True)

我们也可以为某一个单独的子图设置共享:

  1. fig=plt.figure()
  2. ax1 = plt.subplot(211)
  3. ax2 = plt.subplot(212, sharex = ax1)

下面看一个简单的例子, 下面的setp表示Set a property, 是用来设置坐标轴的属性的:

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. t = np.arange(0.01, 5.0, 0.01)
  4. s1 = np.sin(2 * np.pi * t)
  5. s2 = np.exp(-t)
  6. s3 = np.sin(4 * np.pi * t)
  7. ax1 = plt.subplot(311)
  8. plt.plot(t, s1)
  9. plt.setp(ax1.get_xticklabels(), fontsize=6)
  10. # share x only
  11. ax2 = plt.subplot(312, sharex=ax1)
  12. plt.plot(t, s2)
  13. # make these tick labels invisible
  14. plt.setp(ax2.get_xticklabels(), visible=False)
  15. # share x and y
  16. ax3 = plt.subplot(313, sharex=ax1, sharey=ax1)
  17. plt.plot(t, s3)
  18. plt.xlim(0.01, 5.0)
  19. plt.show()
Python数据处理之Matplotlib学习

 

科学绘图

如果想要使用 matplotlib 绘制一些论文需要的图像,可以使用 Science Plots 这个库。我们可以直接使用 pip 来进行安装。

  1. # for lastest release (from PyPI)
  2. pip install SciencePlots

使用的时候,只需要在最开始指定样式即可,详细的样式说明可以查看链接Science Plots

  1. plt.style.use(['science','ieee','no-latex'])

当然也可以只针对某一个图像指定样式:

  1. with plt.style.context(['science', 'ieee']):
  2.     plt.figure()
  3.     plt.plot(x, y)
  4.     plt.show()

SciencePlots 默认使用 serif 字体,如果想要更换字体,可以使用下面的方式:

  1. import matplotlib.pyplot as plt
  2. plt.style.use('science')
  3. plt.rcParams.update({
  4.     "font.family": "serif",   # specify font family here
  5.     "font.serif": ["Times"],  # specify font here
  6.     "font.size":11})          # specify font size here

特别的,我们可以通过更换字体使得 SciencePlots 支持中文。具体来说,首先下载字体,收集的一些字体。接着将下载的字体文件复制到 site-packages/matplotlib/mpl-data/fonts/ttf,最后修改 SciencePlots 的默认字体即可。

更多关于 SciencePlots 常见的问题,可以查看链接,SciencePlots FAQ

 

常用属性设置

matplotlib绘制的图形可以设置各种属性,比如设置坐标系的刻度,标题,标签等属性。 matplotplib绘制图形时,基于X, Y轴坐标系绘图。我们可以设置X, Y坐标的各种属性,比如刻度,范围,标签等属性。

matplotlib 保存图像

关于图像的保存, 可以直接使用下面的方式.

  1. plt.savefig("filename.png")

 

matplotlib 刷新图像

有的时候我们会使用 for 循环来保存多个图像,这个时候每次保存新的图像都要对之前的图像进行清空,否则所有的图像内容都会叠加在一起。这个使用 plt.cla() 即可进行清空画布。

  1. for camera_id, camera_flow in camera_interval_flow.items():
  2.     plt.cla() # 清空图片
  3.     ax.plot(camera_flow) # 绘制曲线
  4.     plt.savefig("{}.png".format(camera_id)) # 图像保存

 

matplotlib显示中文

我们在开头加上下面的代码即可正常显示中文.

  1. from pylab import * # 设置显示中文
  2. mpl.rcParams['font.sans-serif'] = ['SimHei']
  3. plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

关于这里字体名称的设置,我们可以通过下面的方式来进行查看:

  1. import matplotlib
  2. a=sorted([f.name for f in matplotlib.font_manager.fontManager.ttflist])
  3. for i in a:
  4.     print(i)

这里会打印出所有的注册的字体的名称,大致如下所示:

Python数据处理之Matplotlib学习

可以使用「FZShuTi」表示方正舒体。

 

可以显示 Latex 的公式

为了使得 matplotlib 可以显示 latex 中的公式,我们需要指定一些参数,如下所示:

  1. import matplotlib.pyplot as plt
  2. plt.rcParams.update({
  3.     "text.usetex": True,
  4.     "font.family": "serif",
  5.     "font.serif": ["Palatino"],
  6. })

我们可以看一个下面的例子,绘制柱状图,此时 xticks 中含有数学公式:

  1. fig = plt.figure(figsize=(7, 5))
  2. ax = fig.add_subplot(1, 1, 1)
  3. menMeans = (1, 2, 3, 4, 5, 6, 7)
  4. menStd = [i/5 for i in [7, 6, 5, 4, 3, 2, 1]]
  5. ind = np.arange(N)    # the x locations for the groups
  6. width = 0.35       # the width of the bars: can also be len(x) sequence
  7. ax.bar(ind, menMeans, width, yerr=menStd)
  8. plt.xticks(ind, ('$\\alpha=0.001$', '$\\alpha=0.01$', '$\\alpha=0.1$', '$\\alpha=1$', '$\\alpha=5$', '$\\alpha=10$', '$\\alpha=100$'))
  9. ax.xaxis.set_tick_params(labelsize=12)
  10. plt.ylim(0, 10) # 设置 y 轴的范围
  11. plt.yticks(np.arange(0, 10, 0.5)) # 设置 y 轴的显示
  12. ax.yaxis.set_tick_params(labelsize=12)
  13. plt.show()

最终的结果如下所示:

Python数据处理之Matplotlib学习

 

数字与颜色的转换-map number to color

  1. import matplotlib.cm as cm
  2. print(cm.hot(0.3))

也可以使用下面的样式进行绘制:

  1. cmap = plt.get_cmap('rainbow', 12)

参考资料: How to map number to color using matplotlib's colormap?

 

设置 x 和 y 轴的范围

我们可以使用 set_xlim 或是 set_ylim 来控制 x 和 y 轴的范围,如下所示:

  1. axes = plt.gca()
  2. axes.set_xlim([xmin,xmax])
  3. axes.set_ylim([ymin,ymax])

 

设置标题,坐标刻度

  1. fig = plt.figure()
  2. ax = fig.add_subplot(1,1,1)
  3. # 设置标题
  4. ax.set_title('Test Title')
  5. major_ticks = np.arange(0, 101, 20)
  6. minor_ticks = np.arange(0, 101, 5)
  7. # 设置刻度
  8. ax.set_xticks(major_ticks)
  9. ax.set_xticks(minor_ticks, minor=True)   # 这个是短线
  10. ax.set_yticks(major_ticks)
  11. ax.set_yticks(minor_ticks, minor=True)
  12. # 设置 X, Y 轴 标签
  13. ax.set_xlabel("X axis")
  14. ax.set_ylabel("Y axis")
  15. # 设置网格                                                                       
  16. ax.grid(which='minor', alpha=0.2)
  17. ax.grid(which='major', alpha=0.5)
  18. # 添加文字
  19. ax.text(42.5, 50, "Hello World")
  20. fig.show()

可以看到下面的效果

Python数据处理之Matplotlib学习

当我们不想要显示刻度的时候,我们也可以将刻度不显示,使用下面的方式可以关闭刻度的显示:

  1. ax.set_xticks([])
  2. ax.set_yticks([])

如果我们想要只显示 y 轴的格子线,可以使用以下的方式:

  1. ax1.grid(axis='y', which='major', alpha=0.4, linestyle='--')

最终的效果会如下所示:

Python数据处理之Matplotlib学习

 

设置标题位置

直接使用 set_title 会默认将标题生成在图像的上部。但是有的时候我们需要自动调整 title 的位置。我们可以通过设置 set_title 中的参数 y 来改变 title 的位置。下面看一个简单的例子,显示默认生成的标题的位置:

  1. fig, ax = plt.subplots(figsize=(6, 3), subplot_kw=dict(aspect="equal"))
  2. ax.set_title("Title Position")

生成的结果如下所示:

Python数据处理之Matplotlib学习

上面是默认生成的标题的位置,我们可以通过控制 y 来修改标题的位置。如下所示:

  1. fig, ax = plt.subplots(figsize=(6, 3), subplot_kw=dict(aspect="equal"))
  2. ax.set_title("Title Position", y=1.5)

这个时候看生成的效果,可以看到他的标题的位置就在图像的上方一些:

Python数据处理之Matplotlib学习

参考资料Python Matplotlib figure title overlaps axes label when using twiny

这里除了使用 y 来控制标题的位置之后,还可以使用 pad 来控制间距。如下所示:

  1. ax.set_title(u'这是标题', fontsize=24, pad=30)

 

设置 x-label 和 y-label 的间距

当我们设置了 x 和 y 轴的 label 之后,我们有的时候希望他距离我们的坐标距离远一些,这个时候可以使用 labelpad 来控制间距。

  1. ax.set_ylabel("y 的 Label", labelpad=30)

 

加入文字

对于文字, 我们可以再外面加上边框等. 上面是在文字周围加上边框, 底色是红色.

  1. text(x, y, s, bbox=dict(facecolor='red', alpha=0.5))

例如下面是对MNIST降维的结果

  1. ax.text(np.mean(v_x[ix][:,0]), np.mean(v_x[ix][:,1]), key, fontsize=18, bbox=dict(facecolor='white', alpha=0.5))
Python数据处理之Matplotlib学习

关于这张图片的详细生成过程, 可以参考链接t-SNE与AE对MNIST可视化

 

设置坐标轴范围

有的时候需要设置坐标轴的范围,这个需要使用 xlim 和 ylim 来分别进行设置。一般设置完毕之后,还可以配合 xticks 和 yticks 来设置坐标轴的内容。如下面的例子:

  1. fig = plt.figure(figsize=(7, 5))
  2. ax = fig.add_subplot(1, 1, 1)
  3. plt.xlim(0, 10) # 设置 x 轴的范围
  4. plt.xticks(np.arange(0, 10, 2)) # 设置 x 轴的显示
  5. plt.ylim(0, 10) # 设置 y 轴的范围
  6. plt.yticks(np.arange(0, 10, 0.5)) # 设置 y 轴的显示
  7. ax.yaxis.set_tick_params(labelsize=12)
  8. plt.show()

最终的效果如下所示,可以看到 x 和 y 轴的显示间隔是不一样的,同时字体大小也是不一样的:

Python数据处理之Matplotlib学习

 

设置坐标轴刻度与坐标轴名称

注意, 在图中有两个部分,我把他叫做坐标轴刻度与刻度名称坐标轴本身的名称。我们通过下面一个小例子来看一下是如何来进行设置他们的。

  1. from pylab import * # 设置显示中文
  2. mpl.rcParams['font.sans-serif'] = ['SimHei']
  3. plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
  4. x = np.linspace(0, 1, 100)
  5. fig = plt.figure(figsize=(12,8))
  6. ax = fig.add_subplot(1,1,1)
  7. ax.set_title(u'设置曲线颜色与图例', fontsize=17)
  8. # 绘制图形
  9. ax.plot(x, x ** 2, 'b.', label=r'$y = x^{2}$')
  10. # 设置坐标轴的标签
  11. ax.yaxis.set_tick_params(labelsize=15) # 设置y轴的字体的大小
  12. ax.set_xticks(np.linspace(0, 1, 11)) # 设置xticks出现的位置
  13. xticks = [i if i in [0, 0.5, 0.8, 1.0] else '' for i in np.linspace(0, 1, 11)] # 只显示特定数字
  14. ax.set_xticklabels(xticks, rotation=-45, fontsize=17) # 设置xticks的值
  15. # 设置坐标轴名称
  16. ax.set_ylabel("这是Y轴", fontsize='xx-large')
  17. ax.set_xlabel('这是X轴',  fontsize='xx-large')
  18. # 自动生成图例
  19. ax.legend(fontsize=17)
  20. # 设置图像x,y轴的范围,都是从0-1
  21. ax.axis([0, 1, 0, 1])
  22. fig.show()

这上面的内容包括:

  • 设置坐标轴刻度的间隔;
  • 设置坐标轴刻度的名称,调整大小和倾斜角度;
  • 设置 x 轴,y 轴的名称;
Python数据处理之Matplotlib学习

设置坐标轴为log scale

有的时候,我们需要设置坐标轴为 log scale,我们可以使用 plt.yscale 进行设置。可以参考下面的代码:

  1. dt = 0.01
  2. x = np.arange(-50.0, 50.0, dt)
  3. y = np.arange(0, 100.0, dt)
  4. fig = plt.figure()
  5. ax = fig.add_subplot(1,1,1)
  6. ax.plot(x, y)
  7. # 设置y scale
  8. plt.yscale('log')
  9. plt.ylabel('logy') # 设置y轴的label

最后绘制出来的结果如下图所示, 看y轴的刻度, 可以看到此时是log scale了:

Python数据处理之Matplotlib学习

 

设置曲线颜色,图例

  1. # 设置显示中文
  2. from pylab import *
  3. mpl.rcParams['font.sans-serif'] = ['SimHei']
  4. plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
  5. x = np.linspace(0, 1,100)
  6. fig = plt.figure()
  7. ax = fig.add_subplot(1,1,1)
  8. ax.set_title(u'设置曲线颜色与图例')
  9. # 四个参数分别表示x,y轴数据,'b--'表示颜色是蓝色样式是虚线,最后一个表示标签,支持LaTex
  10. ax.plot(x, x ** (1/8), 'b--', label=r'$y = x^{1/8}$')
  11. ax.plot(x, x ** 8, 'r--', label=r'$y = x^{8}$')
  12. ax.plot(x, x ** (1/2), 'r.', label=r'$y = x^{1/2}$')
  13. ax.plot(x, x ** 2, 'b.', label=r'$y = x^{2}$')
  14. ax.plot(x, x, 'g-', label=r'$y = x$')
  15. # 自动生成图例
  16. ax.legend()
  17. # 设置图像x,y轴的范围,都是从0-1
  18. ax.axis([0, 1, 0, 1])
  19. fig.show()

上面的代码运行完毕后我们可以看到如下的图像:

Python数据处理之Matplotlib学习

关于一些常用的样式,我们记录一下:

『线的样式』linestyle=

  • '-' 默认实线
  • '--' 虚线
  • '-.' 间断线
  • ':' 点状线

常见的『颜色』有:

  • 'b' blue
  • 'g' green
  • 'r' red
  • 'c' cyan
  • 'm' magenta
  • 'y' yellow
  • 'k' black(黑色)
  • 'w' white

 

图例与 pandas 结合使用

有的时候,我们的使用 pandas 的数据来进行绘图的时候。图例是 dataframe 中某一列的数据,这个时候我们就可以使用下面的方式插入图例:

  1. plt.legend(legend.values,loc=4)

参考资料Pandas matplotlib.pyplot add legend by a column value

 

关于图例位置自定义

要是我们想要自定义图例的位置,比如说希望图例出现在曲线的上面,或者周围,我们可以使用 ax.text 来进行实现。我们看一下下面的这个例子:

  1. from pylab import * # 设置显示中文
  2. mpl.rcParams['font.sans-serif'] = ['SimHei']
  3. plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
  4. x = np.linspace(0, 1,100)
  5. fig = plt.figure(figsize=(12,8))
  6. ax = fig.add_subplot(1,1,1)
  7. ax.set_title(u'设置曲线颜色与图例')
  8. # 四个参数分别表示x,y轴数据,'b--'表示颜色是蓝色样式是虚线,最后一个表示标签,支持LaTex
  9. ax.plot(x, x ** 8, 'r--', label=r'$y = x^{8}$')
  10. ax.plot(x, x ** 2, 'b.', label=r'$y = x^{2}$')
  11. # 手动设置图例
  12. ax.text(x[-10], 0.9*(x ** 8) [-10], r'$y = x^{8}$', fontsize=17)
  13. ax.text(x[-26], 1.2*(x ** 2) [-26], r'$y = x^{2}$', fontsize=17)
  14. # 自动生成图例
  15. ax.legend()
  16. # 设置图像x,y轴的范围,都是从0-1
  17. ax.axis([0, 1, 0, 1])
  18. fig.show()

最终的实现的效果如下图所示,可以看到在两条曲线周围都有了图例:

Python数据处理之Matplotlib学习

 

绘制图像的样式

绘制xkcd样式图片

我们可以绘制漫画风格的图片,只需要在初始设定 plt.xkcd() 即可:

  1. plt.xkcd()
  2. fig = plt.figure()
  3. ax = fig.add_subplot(1, 1, 1)
  4. np.random.seed(7)
  5. x = np.linspace(1, 10, 50)
  6. y = 2*x + 0.5*x**2 + 0.3*x**4 - 0.025*x**5 + 5*np.random.rand(50)
  7. ax.scatter(x, y)

最终的绘制效果如下图所示:

Python数据处理之Matplotlib学习

我们需要注意的是,在设置 xkcd 样式的时候,可以写成下面这样(使用 with 包住),这样可以保证只有当前的图像应用这个风格:

  1. with plt.xkcd():
  2.     # This figure will be in XKCD-style
  3.     fig1 = plt.figure()
  4.     # ...
  5. # This figure will be in regular style
  6. fig2 = plt.figure()

关于 xkcd 样式中文的设置,需要在定义风格之后进行,下面是一个例子:

  1. plt.xkcd()
  2. plt.rcParams['font.family'] = ['FZShuTi']

下面看一个简单的例子,包含中文的 xkcd 样式的图像:

  1. plt.xkcd()
  2. plt.rcParams['font.family'] = ['FZShuTi'] # 这个需要在设置样式之后再设置
  3. fig = plt.figure()
  4. ax = fig.add_subplot(1, 1, 1)
  5. ax.set_title(u'是否考虑自己未来的规划', fontsize=25)
  6. x = np.arange(3)*1.2
  7. y = [137, 140, 176] # 有
  8. z = [33, 45, 38] # 没有
  9. sum = [i+j for i,j in zip(y,z)] # 计算每个年纪所占的比例
  10. y =  [i/j for i,j in zip(y,sum)]
  11. z = [i/j for i,j in zip(z,sum)]
  12. w=0.3
  13. # 绘制多个bar在同一个图中, 这里需要控制width
  14. plt.bar(x-w/2, y, width=w, align='center', label='有')
  15. plt.bar(x+w/2, z, width=w, align='center', label='没有')
  16. ax.set_xticks(x) # 设置xticks出现的位置
  17. ax.set_xticklabels(['高一', '高二', '高三'], rotation='30', fontsize='xx-large')
  18. ax.plot(x, y, c='green') # 画出曲线
  19. ax.legend(bbox_to_anchor=(1, 0.95)) # 绘制图例
  20. plt.show()

最终的输出格式如下所示:

Python数据处理之Matplotlib学习

关于具体的说明,可以参考链接,用matplotlib库绘制手涂风格桥表

 

图像的样式概览

除了上面的风格之外,我们还有不同类型的风格可以进行设置。例如下面是设置为默认的风格,完整的风格间下面的参考链接:

  1. # 设置画图的style
  2. matplotlib.style.use('default')

matplotlib风格类型: Style sheets reference

 

绘制其他样式

对于绘制其他样式的图片,只需要修改plt.style.use即可,可以看下面的简单的例子:

  1. # 生成随机数据
  2. np.random.seed(7)
  3. x = np.linspace(1, 12, 10)
  4. y = 2*x + 0.7*x**2 - 20*np.sin(x) - 20*np.cos(x) + 5*np.random.rand(10)
  5. plt.style.use("ggplot") # 使用美观的样式
  6. plt.scatter(x, y)
Python数据处理之Matplotlib学习

 

设置图像颜色风格

除了上面设置图像的风格之外,我们还可以设置图像的颜色的风格。我们可以使用下面的命令来设置颜色的样式。

  1. plt.set_cmap('RdBu')

我们来看一下最终的效果,使用柱状图来举一个例子。

  1. x = np.arange(3)*1.2
  2. y = [4, 9, 2]
  3. z = [1, 2, 3]
  4. k = [11, 12, 13]
  5. ax = plt.subplot(111)
  6. plt.set_cmap('RdBu')
  7. w=0.3
  8. # 绘制多个bar在同一个图中, 这里需要控制width
  9. plt.bar(x-w, y, width=w, align='center')
  10. plt.bar(x, z, width=w, align='center')
  11. plt.bar(x+w, k, width=w, align='center')
  12. ax.set_xticks(x) # 设置xticks出现的位置
  13. ax.set_xticklabels(['1','2','3'], rotation='vertical', fontsize = 'xx-large')
  14. ax.autoscale(tight=True)
  15. plt.show()

这是一个绘制多个柱状图的方式,最终的效果如下所示。

Python数据处理之Matplotlib学习

 

设置图像颜色

除了上面使用指定的颜色,我们还可以指定我们需要的颜色,还是使用上面的柱状图作为例子我们简单来看一下。

其实基本是一样的,只是在绘图的时候指定了颜色,color=.。这三种颜色搭配我感觉还是不错的,在这里放一下(最终的效果见下面)。

  • #e0109c
  • #1b71f1
  • #9eed3b
  1. x = np.arange(3)*1.2
  2. y = [4, 9, 2]
  3. z = [1, 2, 3]
  4. k = [11, 12, 13]
  5. ax = plt.subplot(111)
  6. w=0.3
  7. # 绘制多个bar在同一个图中, 这里需要控制width
  8. plt.bar(x-w, y, width=w, color='#e0109c', align='center')
  9. plt.bar(x, z, width=w, color='#1b71f1', align='center')
  10. plt.bar(x+w, k, width=w, color='#9eed3b', align='center')
  11. ax.set_xticks(x) # 设置xticks出现的位置
  12. ax.set_xticklabels(['1','2','3'], rotation='vertical', fontsize = 'xx-large')
  13. ax.autoscale(tight=True)
  14. plt.show()

上面的颜色,绘制出来的效果如下所示。

Python数据处理之Matplotlib学习

 

常用图像

我们在数据分析的时候,经常会用到各种各样的图像,我们就在这里总结一下。

水平线

我们使用 axhline 可以直接绘制水平线。下面看一个例子:

  1. import seaborn as sns
  2. import matplotlib.pyplot as plt
  3. import numpy as np
  4. import pandas as pd
  5. x = np.array([2, 2, 4, 4])
  6. y = np.array([5, 10, 10, 15])
  7. isBool = np.array([TrueFalseTrueFalse])
  8. data = pd.DataFrame(
  9.     np.column_stack((x, y, isBool)),
  10.     columns=["x", "y", "someBoolean"]
  11. )
  12. ax = sns.lineplot(x="x", y="y", hue="someBoolean", data=data)
  13. ax.axhline(y=7, c='red', linestyle='dashed', label="h7")
  14. ax.axhline(y=15, c='blue', linestyle='dashed', label="h15")
  15. plt.legend()
  16. plt.show()

绘制的结果如下图所示,可以看到包含两个水平线:

Python数据处理之Matplotlib学习

参考资料matplotlib-axhline

 

线形图(折线图)

这个就有点类似把一些散点连起来,我们使用Axes.plot进行绘制

  1. fig = plt.figure()
  2. ax = fig.add_subplot(1,1,1)
  3. x = np.arange(10)
  4. y = x**2
  5. ax.plot(x,y)
  6. fig.show()
Python数据处理之Matplotlib学习 下面我们看一个稍微复杂的折线图,完整的代码如下:
  1. plt.style.use(['science','ieee','no-latex']) # 设置格式
  2. fig, ax = plt.subplots(figsize=(6, 4), nrows=1,ncols=1)
  3. # 定义数据
  4. x_indexs = [0, 1, 2, 3, 4, 5]
  5. heights = [0.98, 0.93, 0.83, 0.72, 0.68, 0.66]
  6. # 绘图
  7. ax.plot(x_indexs, heights, '--', linewidth=2, marker='o', markersize=4) # 绘制折线图
  8. # 绘制竖线
  9. for x_index, height in zip(x_indexs,heights):
  10.     ax.plot([x_index, x_index], [0, height], 'k--', linewidth=0.5)
  11. # 设置图的样式
  12. ax.set(ylim=[0.5, 1]) # 设置 y 轴范围
  13. ax.set_xticks(x_indexs) # 设置xticks出现的位置
  14. ax.set_xticklabels(['$\gamma$=0.01','$\gamma$=0.1','$\gamma$=0.2', '$\gamma$=0.5', '$\gamma$=0.9', '$\gamma$=0.99'])
  15. ax.set_ylabel('F-measure')
最终的效果如下所示: Python数据处理之Matplotlib学习  

绘制误差区间

例如现在有一个 3×5×20 的数据,我们想要绘制三条折线,同时绘制出他的误差范围。于是数据生成与绘制的代码如下所示(我们可以理解为 5×20 是生成了 5 条实验数据,我们想要绘制 20 个点。但是因为有 5 条数据,因此每隔位置其实有 5 个数据,因此我们计算他的均值和方差,绘制出误差区间):
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. import seaborn as sns
  4. if __name__ == '__main__':
  5.     data =  np.random.random((3, 5, 20))
  6.     data[1] +=  5
  7.     data[2] +=  10
  8.     # Reward 与时间的关系
  9.     clrs = sns.color_palette("husl", 5)
  10.     fig = plt.figure(figsize=plt.figaspect(0.6))
  11.     ax = fig.add_subplot(1,1,1)
  12.     labels = ['A', 'B', 'C']
  13.     for i, label in enumerate(labels):
  14.         steps = list(range(20))
  15.         mean = np.mean(data[i], 0) # 计算均值
  16.         std = np.std(data[i], 0) # 计算方差
  17.         ax.plot(steps, mean, label=label, c=clrs[i])
  18.         ax.fill_between(steps, mean-std, mean+std ,alpha=0.3, facecolor=clrs[i])
  19.     plt.legend()
  20.     plt.show()
运行上面的代码,可以得到如下所示的图像,其中有颜色的阴影部分表示误差范围: Python数据处理之Matplotlib学习  

绘制箭头

我们可以使用 arrow 来在 Axes 上面绘制一个箭头。arrow(x, y, dx, dy)会有四个参数,意思如下:This draws an arrow from (x,y) to (x+dx,y+dy). 我们尝试以下的代码:
  1. fig = plt.figure(figsize=plt.figaspect(1))
  2. ax1 = fig.add_subplot(111)
  3. ax1.arrow(x=0, y=0, dx=0.5, dy=0.5, width=0.01)
  4. plt.show()
最终的结果如下图所示: Python数据处理之Matplotlib学习  

柱状图

纵向的柱状图

  1. fig = plt.figure(figsize=(7,5))
  2. ax = fig.add_subplot(1,1,1)
  3. bar_data = [5, 20, 15, 25, 10]
  4. bar_labels = ['Tom', 'Dick', 'Harry', 'Slim', 'Jim']
  5. plt.bar(range(len(bar_data)), bar_data, tick_label=bar_labels)
  6. plt.show()
Python数据处理之Matplotlib学习

堆叠柱状图

我们可以将两个柱状图以堆叠的形式画在一起。下面看一个简单的例子。
  1. data = pd.DataFrame({'A': [1,3,2,4], 'B': [4,2,3,1], 'index': ['test1', 'test2', 'test3', 'test4']})
创建的数据样例如下所示: Python数据处理之Matplotlib学习 我们希望画两个柱状图,第一个柱状图的高度就是上面表格中的A,第二个柱状图从A的位置开始画起,他的高度是B,这样就是两个柱状图堆叠在一起的效果。
  1. plt.rcParams['figure.figsize'] = (10, 6)
  2. plt.bar(x='index', height='A', data=data, width=1.0, label='下')
  3. plt.bar(x='index', height='B', bottom='A', data=data, width=1, label='上')
  4. ax = plt.gca()
  5. ax.legend(prop=myfont, bbox_to_anchor=(1.0, 0.9))
最终的效果如下所示: Python数据处理之Matplotlib学习  

横向柱状图

将上面的plt.bar替换为plt.barh可以画出横向的柱状图. 一般用在labels比较长,或是比较多的时候,比如说我们可以绘制出下面的图像. Python数据处理之Matplotlib学习 参考链接 : matplotlib绘图——柱状图  

绘制多条柱状图

有的时候,我们需要绘制多条柱状图在一起,从而来进行比较,可以使用下面的方式进行绘制.(其实这一部分的内容是和上面介绍设置图像颜色, 图像风格是重复的, 在这里再简单说明一下)
  1. x = np.arange(3)*1.2
  2. y = [4, 9, 2]
  3. z = [1, 2, 3]
  4. k = [11, 12, 13]
  5. ax = plt.subplot(111)
  6. w=0.3
  7. # 绘制多个bar在同一个图中, 这里需要控制width
  8. plt.bar(x-w, y, width=w, color='#e0109c', align='center')
  9. plt.bar(x, z, width=w, color='#1b71f1', align='center')
  10. plt.bar(x+w, k, width=w, color='#9eed3b', align='center')
  11. ax.set_xticks(x) # 设置xticks出现的位置
  12. ax.set_xticklabels(['1','2','3'], rotation='vertical', fontsize = 'xx-large')
  13. ax.autoscale(tight=True)
  14. plt.show()
绘制的结果如下: Python数据处理之Matplotlib学习 那么这个图什么时候可以用到呢,就是我们可以展示同一类的 TP, FP, FN 这些指标。如下图所示(下面是使用 NSL-KDD 做的实验的结果): Python数据处理之Matplotlib学习 参考链接:Python matplotlib multiple bars  

包含标准差的柱状图

有的时候我们柱状图上面需要包含标准差,可以使用参数 yerr 来进行设置,如下所示:
  1. fig = plt.figure(figsize=(7, 5))
  2. ax = fig.add_subplot(1, 1, 1)
  3. menMeans = (1, 2, 3, 4, 5, 6, 7)
  4. menStd = [i/5 for i in [7, 6, 5, 4, 3, 2, 1]]
  5. ind = np.arange(N)    # the x locations for the groups
  6. width = 0.35       # the width of the bars: can also be len(x) sequence
  7. ax.bar(ind, menMeans, width, yerr=menStd)
  8. plt.xticks(ind, ('$\\alpha=0.001$', '$\\alpha=0.01$', '$\\alpha=0.1$', '$\\alpha=1$', '$\\alpha=5$', '$\\alpha=10$', '$\\alpha=100$'))
  9. ax.xaxis.set_tick_params(labelsize=12)
  10. plt.ylim(0, 10) # 设置 y 轴的范围
  11. plt.yticks(np.arange(0, 10, 0.5)) # 设置 y 轴的显示
  12. ax.yaxis.set_tick_params(labelsize=12)
  13. plt.show()
最终的结果如下所示: Python数据处理之Matplotlib学习 参考资料Stacked Bar Graph yerr 同样的,上面的 yerr 是可以设置样式的。例如可以更换颜色,粗细等。我们通过下面的方式进行更换,error_kw 这个参数的设置
  1. ax.bar(ind, menMeans, width, color='k', yerr=menStd, error_kw=dict(elinewidth=2, ecolor='#7f8c8d', capsize=5))
最终可以获得以下效果的图像: Python数据处理之Matplotlib学习 如果我们想要将其转换为横着的柱状图,需要将上面的 yerr 更换为 xerr。下面来看一个简单的例子(这种情况更加适用于每个柱的标题比较长):
  1. ax.barh(x_ticks, data_mean, xerr=data_std, error_kw=dict(elinewidth=2, ecolor='#7f8c8d', capsize=3))
运行上面的代码可以得到下面的结果,唯一需要注意的就是使用 barh 的时候需要使用 xerr 而不是 yerr,即误差画在「y-轴」方向。 Python数据处理之Matplotlib学习   参考资料Matplotlib学习---用matplotlib画误差线(errorbar)  

使用柱状图和折线图显示累计占比

对于某一类数据来说我们可以首先统计不同区间数据的数量。
  1. binRange = [0, 784, 1024, 4096, 100000]
  2. sample_num, _ = np.histogram(pcaps_size_list, bins=binRange)
  3. print(sample_num)
  4. """
  5. [46054  1413  3437  3691]
  6. """
接着我们统计每一个区间的数据所占的比例,这里相当于是对上面的 list 进行累加,接着除以总数,如下所示,计算出每一个区间的占比:
  1. sample_num_percentage = np.cumsum(sample_num, dtype=float)/sum(sample_num)
  2. print(sample_num_percentage)
  3. """
  4. [0.8435571  0.86943859 0.93239308 1.        ]
  5. """
最后我们通过柱状图和折线图的方式,展示出每一个部分所占比例,同时也可以显示出累计的比例:
  1. # 绘制直方图和折线图
  2. fig = plt.figure()
  3. ax = fig.add_subplot(1,1,1)
  4. fig_index = ['0-784', '784-1024', '1024-4096', '>4096']
  5. # 绘制柱状图
  6. ax.bar(fig_index, sample_num)
  7. ax.set_ylim([0, 70000]) # 设置 y 轴范围
  8. ax.set_xlabel('Pcap Size (Byte)') # 设置 x 轴的 label
  9. ax.set_ylabel('Pcap Number') # 设置 y 轴的 label
  10. # 绘制折线图
  11. ax_twin = ax.twinx() # 次坐标
  12. ax_twin.plot(fig_index, sample_num_percentage, marker='o', markersize=3)
  13. ax_twin.set_ylim([0, 1.1])
  14. # 添加文字
  15. for tmp_index, tmp_percentage in zip(fig_index, sample_num_percentage):
  16.     ax_twin.text(tmp_index, 1.03* tmp_percentage, "{:<6.2f}".format(tmp_percentage))
最终的可视化结果如下所示: Python数据处理之Matplotlib学习  

饼图的绘制

基础饼图的绘制

我们只需要给定饼图中每一块的大小,每一块的 label,每一块是否要突出,即可绘制出一个最基础的饼图。
  1. # Pie chart, where the slices will be ordered and plotted counter-clockwise:
  2. labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
  3. sizes = [15, 30, 45, 10]
  4. explode = (0, 0.1, 0, 0)  # only "explode" the 2nd slice (i.e. 'Hogs')
  5. fig1, ax1 = plt.subplots()
  6. ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
  7.         shadow=True, startangle=90)
  8. ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.
  9. plt.show()
绘制的效果最终如下所示: Python数据处理之Matplotlib学习  

对饼图进行 Label

下面代码只需要修改 data,title,和 recipe 即可,后面的都可以不进行修改。
  1. fig, ax = plt.subplots(figsize=(7, 5), subplot_kw=dict(aspect="equal"))
  2. y1 = [135, 148, 166]
  3. y3 = [73, 95, 93]
  4. y4 = [85, 99, 82]
  5. y5 = [114, 121, 122]
  6. y6 = [105, 107, 100]
  7. data = [np.sum(i) for i in [y1, y2, y3, y4, y5, y6]]
  8. title = ["开设职业生涯规划课程",
  9.           "举办职业规划讲座",
  10.           "在学校开通职业规划评价系统",
  11.           "在学校设立专门的职业指导中心",
  12.           "创建丰富多彩的职业体验课程",
  13.           "加强教师和家长的指导"]
  14. recipe = ['{} {:<3.2f} %'.format(i,j/np.sum(data)*100) for i,j in zip(title, data)] # 设置标题
  15. # 下面的不需要修改
  16. wedges, texts = ax.pie(data, wedgeprops=dict(width=0.4), startangle=-40)
  17. bbox_props = dict(boxstyle="square,pad=0.3", fc="w", ec="k", lw=0.72)
  18. kw = dict(arrowprops=dict(arrowstyle="-"),
  19.           bbox=bbox_props, zorder=0, va="center")
  20. for i, p in enumerate(wedges):
  21.     ang = (p.theta2 - p.theta1)/2. + p.theta1
  22.     y = np.sin(np.deg2rad(ang))
  23.     x = np.cos(np.deg2rad(ang))
  24.     horizontalalignment = {-1: "right", 1: "left"}[int(np.sign(x))]
  25.     connectionstyle = "angle,angleA=0,angleB={}".format(ang)
  26.     kw["arrowprops"].update({"connectionstyle": connectionstyle})
  27.     ax.annotate(recipe[i], xy=(x, y), xytext=(1.35*np.sign(x), 1.4*y),
  28.                 horizontalalignment=horizontalalignment, **kw)
  29. ax.set_title(u"您认为学校开展职业生涯规划教育的措施有哪些", fontsize=25, y=1.2)
  30. plt.show()
最终生成的效果如下所示: Python数据处理之Matplotlib学习 上面有一些可以修改的地方:
  • 关于 label 的位置,我们可以通过 xytext 来控制,及上面的 1.35*np.sign(x), 和 1.4*y, 可以控制前面的系数, 1.35 和 1.4,来使我们的 label 的位置不一样;
  • 控制 label 的字体大小,可以直接在 axannotate 部分增加参数 fontsize 即可。如下面的例子:
  1. for x, y, label, size in zip(X, Y, labels, sizes):
  2.     ax.annotate(label, (x, y), fontsize=size)
 

直方图

直方图X轴一般是统计的样本,而Y轴一般是样本对应的统计度量。

为了构建直方图,第一步是将值的范围分段,即将整个值的范围分成一系列间隔,然后计算每个间隔中有多少值。 这些值通常被指定为连续的,不重叠的变量间隔。 间隔必须相邻,并且通常是(但不是必须的)相等的大小。在 matplotlib 中可以使用Axes.hist方法绘制直方图。

  1. fig = plt.figure()
  2. ax = fig.add_subplot(1,1,1)
  3. data = np.random.normal(0,20,1000) # 在0-20之间产生1000个随机数
  4. bins = np.arange(-100,100,5) # 产生区间刻度
  5. ax.hist(data,bins=bins)
  6. fig.show()
  Python数据处理之Matplotlib学习 我们也可以将多个直方图绘制在一起,同时可以加上直方图的密度曲线,我们看下面的一个例子:
  1. import random
  2. from scipy import stats
  3. # 产生测试数据
  4. x = [random.gauss(3,1) for _ in range(400)]
  5. y = [random.gauss(4,2) for _ in range(400)]
  6. # 拟合密度曲线
  7. kde1 = stats.gaussian_kde(x)
  8. kde2 = stats.gaussian_kde(y)
  9. bins = np.linspace(-10, 10, 100)
  10. # 绘制直方图
  11. plt.hist(x, bins, alpha=0.5, label='x', normed=True, color='#2980b9')
  12. plt.hist(y, bins, alpha=0.5, label='y', normed=True, color='#f39c12')
  13. # 绘制曲线
  14. plt.plot(bins, kde1(bins), lw=4, color='#2980b9')
  15. plt.plot(bins, kde2(bins), lw=4, color='#f39c12')
  16. plt.legend(loc='upper right')
  17. plt.show()
最终的结果如下图所示,同时将两个直方图绘制在一起,并绘制出他的拟合曲线: Python数据处理之Matplotlib学习

散点图

散点图,将所有的数据值在图形中绘制成点,这样有多少数据值在图形中就会有多少个点。通过这些数据点可以看出数据值的分布模式,比如是否有聚类模式,或者相关关系或者发现离群点。在 matplotlib 中可以通过Axes.scatter绘制散点图。

  1. fig = plt.figure()
  2. ax = fig.add_subplot(1,1,1)
  3. x = np.arange(1,100,1)
  4. y = x**2+100*x*np.random.random(len(x))
  5. ax.scatter(x,y)
  6. fig.show()
Python数据处理之Matplotlib学习

散点图的美化

一些比较规整的,类似于表格的数据,也是可以使用散点图进行绘制。我们首先生成样例数据,这里是生成每一年,每一个年龄段的人口的数据。也就是1年,如果年龄段是0-80,也就是一年会有80组数据。
  1. data = []
  2. years = [str(i) for i in list(range(1990, 2020, 1))] # 所有的年份
  3. ages = [str(i) for i in list(range(0, 81, 5))] # 所有的年龄段
  4. populations = [10000*i for i in list(range(0, 81, 5))] # 每个年龄段的人口
  5. for year_index, year in enumerate(years):
  6.     for age_index, age in enumerate(ages):
  7.         data.append([year, age, (1+0.1*year_index)*populations[age_index]])
  8. plot_data = pd.DataFrame(data, columns=['year', 'age', 'population'])
  9. plot_data.head()
生成的数据如下所示: Python数据处理之Matplotlib学习 我们使用散点图对上面的数据进行可视化:
  1. plt.rcParams['figure.figsize'] = (18, 8)
  2. plt.scatter(
  3.     x=plot_data['year'],
  4.     y=plot_data['age'],
  5.     c=plot_data['population'],
  6.     s=plot_data['population']*0.0005,
  7.     ec='tab:gray',
  8.     cmap=plt.cm.RdBu_r,
  9.     alpha=0.8)
  10. ax = plt.gca()
  11. # 坐标轴控制
  12. ax.set_xticks([years[i] for i in range(0, len(years), int(len(years)/5))])
  13. ax.set_yticks([ages[i] for i in range(0, len(ages), int(len(ages)/5))])
  14. # 不显示左侧和底部纵坐标轴
  15. ax.spines['left'].set_visible(False)
  16. ax.spines['bottom'].set_visible(False)
  17. # 显示 y 轴网格线
  18. ax.grid(b=False, axis='y', lw=1)
  19. plt.ylabel('Mean Age')
最终的效果如下所示: Python数据处理之Matplotlib学习  

高阶散点图-指定不同类别使用不同颜色

如果散点图中有不同的类别, 同时希望可以对不同类别使用不同的颜色, 并使用图例标注出来, 我们需要依序进行绘制. 以下是一个完整的例子, 详细说明可以查看链接: matplotlib绘图优化-散点图绘制图例
  1. cmap = plt.get_cmap('rainbow', 12) # 数字与颜色的转换
  2. scatter_x = np.array([1,2,3,4,5])
  3. scatter_y = np.array([5,4,3,2,1])
  4. group = np.array([1,3,2,1,3])
  5. cdict = {1: '111', 2: '222', 3: '333'}
  6. fig, ax = plt.subplots()
  7. for key in cdict.keys():
  8.     ix = np.where(group == key)
  9.     ax.scatter(scatter_x[ix], scatter_y[ix], color = cmap(key), label = key, s = 100) # 注意这里color的指定
  10. ax.legend()
  11. plt.show()
最终的结果如下所示: Python数据处理之Matplotlib学习 除了可以控制颜色的不同以外, 我们还可以控制形状的不同, 可以通过简单设置marker来达到效果, 下面有12种不同的marker:
  1. markers = ["8","s","p","P","*","h","H","+","x","X","D","d"]
 

绘制多边形(区间的绘制)

我们可以使用plt.fill进行多边形的绘制,我们先看一个简单的例子:
  1. # 绘制一个多边形的区域
  2. test_x = np.array([1,2,3])
  3. test_y = np.array([4,1,2])
  4. fig, axes = plt.subplots(nrows=1, ncols=1,figsize=(13,7))
  5. axes.fill(test_x,test_y)
Python数据处理之Matplotlib学习 我们可以使用这个方法来绘制一个区间的效果;
  1. # 绘制一个多边形的区域
  2. test_x = np.linspace(0.1, 9.9, 200)
  3. test_y = np.sin(test_x)
  4. fig, axes = plt.subplots(nrows=1, ncols=1,figsize=(13,7))
  5. axes.plot(test_x,test_y,c='r')
  6. axes.fill(np.concatenate([test_x,test_x[::-1]]),np.concatenate([test_y + 1, test_y - 1]))
Python数据处理之Matplotlib学习

箱线图

箱线图可以看出数据的分散程度,异常值等信息,箱线图根据一组数据的以下 5 个统计值进行绘制:

  • 最小值;
  • 第1四分位数;
  • 中位数;
  • 第3四分位数;
  • 最大值;

在 matplotlib 中可以使用Axes.boxplot方法绘制箱线图

  1. fig = plt.figure()
  2. ax = fig.add_subplot(1,1,1)
  3. # 产生 50 个小于 100 的随机数
  4. spread = np.random.rand(50) * 100
  5. # 产生 25 个值为 50 的数据
  6. center = np.ones(25) * 50
  7. # 异常值
  8. outlier_high = np.random.rand(10) * 100 + 100
  9. outlier_low = np.random.rand(10) * -100
  10. data = np.concatenate((spread, center, outlier_high, outlier_low), 0)
  11. ax.boxplot(data)
  12. fig.show()

上面的代码中,我们特意创建了 data 数据,可以推断出该数据的中位数是 50,还有一些其他异常值,绘制的图形如下:

Python数据处理之Matplotlib学习

同样的,我们可以绘制多组数据的箱线图,可以看一下下面的例子:

  1. fig1, ax1 = plt.subplots(figsize=(16,8))
  2. # 产生数据
  3. test1 = np.random.randint(100, 200, 1000)
  4. test2 = np.random.randint(300, 400, 1000)
  5. ax1.boxplot([test1, test2], labels=['test1', 'tets2'])
  6. ax1.set_xticklabels(['test1', 'tets2'], rotation=-45, fontsize=18)
  7. ax1.yaxis.set_tick_params(labelsize=18)

我们只需要把数据使用 List 组合起来即可,上面的代码最终效果如下所示:

Python数据处理之Matplotlib学习

如果想要是的箱线图可以中间有折进去(带有缺口),可以设置 notch=True,最终的结果会如下图所示:

Python数据处理之Matplotlib学习

关于更多箱线图的例子,可以查看链接,Matplotlib Boxplot Demo

 

绘制动态图

除了能绘制上面的静态图像,我们还可以绘制动态图像,下面我们来举一个小例子来说明matplotlib如何绘制动态图像。

简单的动画制作

动态图主要是通过animation模块实现。具体就是matplotlib.animation.FuncAnimation(fig, func)。其中fig代表所绘制的图像。而func可以看作是更新函数,它刷新每一帧的值。

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. import matplotlib.animation as animation
  4. fig = plt.figure()
  5. ax = fig.add_subplot(1,1,1)
  6. x = np.arange(0,2*np.pi,0.01)
  7. line, = plt.plot(x,np.sin(x))
  8. # 更新函数
  9. def update(i):
  10.     line.set_ydata(np.sin(x+i/10))
  11.     return line
  12. animation = animation.FuncAnimation(fig,update,interval=20)
  13. plt.show()

上面的interval表示更新频率,以 ms 计。我们在上面定义了一个 update 函数,该函数可以通过重新设置 y 的值使其动起来。看一下上面的绘制出的效果

Python数据处理之Matplotlib学习

 

通过更新列表更新图像

现在假设我们已经将数据保存在 list 中,我们希望有逐渐向里面添加的动画效果。所以我们在 animate 函数中,每次都比前一步多一个数据。具体代码如下所示:

  1. import matplotlib.pyplot as plt
  2. import matplotlib.animation as animation
  3. fig = plt.figure()
  4. #creating a subplot 
  5. ax1 = fig.add_subplot(1,1,1)
  6. Date = [1,2,3,4,5,6,7,8,9]
  7. Price = [100, 120, 320, 370, 420, 600, 550, 720, 900]
  8. def animate(i):
  9.     xs = Date[:i]
  10.     ys = Price[:i]
  11.     print(xs, ys)
  12.     ax1.clear() # 清除画布
  13.     ax1.plot(xs, ys)
  14.     plt.xlabel('Date')
  15.     plt.ylabel('Price')
  16.     plt.title('Live graph with matplotlib')
  17. ani = animation.FuncAnimation(fig, animate, interval=500)
  18. plt.show()

最终的可视化的效果如下所示:

Python数据处理之Matplotlib学习

参考资料Animations with Matplotlib

 

绘制三维图像

最后,我们来说一下三维图像的绘制。

绘制三维散点图

  1. import numpy as np
  2. # 导入2d,3d的绘图模块
  3. from mpl_toolkits.mplot3d import Axes3D
  4. import matplotlib.pyplot as plt
  5. # x, y, z 均为 0 到 1 之间的 100 个随机数
  6. x = np.random.normal(0, 1, 100)
  7. y = np.random.normal(0, 1, 100)
  8. z = np.random.normal(0, 1, 100)
  9. fig = plt.figure()
  10. ax = Axes3D(fig)
  11. ax.scatter(x,y,z)
  12. plt.show()

最终的效果如下图所示:

Python数据处理之Matplotlib学习

绘制三维线形图

  1. # 载入模块
  2. from mpl_toolkits.mplot3d import Axes3D
  3. import matplotlib.pyplot as plt
  4. import numpy as np
  5. # 生成数据
  6. x = np.linspace(-6 * np.pi, 6 * np.pi, 1000)
  7. y = np.sin(x)
  8. z = np.cos(x)
  9. # 创建 3D 图形对象
  10. fig = plt.figure()
  11. ax = Axes3D(fig)
  12. # 绘制线型图
  13. ax.plot(x, y, z)
  14. # 显示图
  15. plt.show()
  Python数据处理之Matplotlib学习

绘制三维曲面图

  1. # 载入模块
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. from mpl_toolkits.mplot3d import Axes3D
  5. # 创建 3D 图形对象
  6. fig = plt.figure()
  7. ax = Axes3D(fig)
  8. # 生成数据
  9. X = np.arange(-2, 2, 0.1)
  10. Y = np.arange(-2, 2, 0.1)
  11. X, Y = np.meshgrid(X, Y) #注意这一步
  12. Z = np.sqrt(X ** 2 + Y ** 2)
  13. # 绘制曲面图,并使用 cmap 着色
  14. ax.plot_surface(X, Y, Z, cmap=plt.cm.winter)
  15. plt.show()
 

这个上面的meshgrid是用来生成底部的网格的,我们可以看一下x,y是什么

Python数据处理之Matplotlib学习

运行上面的代码,于是我们可以得到下面的图像

Python数据处理之Matplotlib学习

子图的绘制

之前绘制二维图像的时候我们是通过.add_subplot()来绘制子图的,其实在三维的时候也是一样的,只是注意 3D 绘图时要添加 projection='3d' 参数,下面我们看一个具体的例子。

  1. # -*- coding: utf-8 -*
  2. # 载入模块
  3. from mpl_toolkits.mplot3d import Axes3D
  4. import matplotlib.pyplot as plt
  5. import numpy as np
  6. # 创建 1 张画布
  7. fig = plt.figure()
  8. #===============
  9. # 向画布添加子图 1 
  10. ax1 = fig.add_subplot(1, 2, 1, projection='3d')
  11. # 生成子图 1 数据
  12. x = np.linspace(-6 * np.pi, 6 * np.pi, 1000)
  13. y = np.sin(x)
  14. z = np.cos(x)
  15. # 绘制第 1 张图
  16. ax1.plot(x, y, z)
  17. #===============
  18. # 向画布添加子图 2
  19. ax2 = fig.add_subplot(1, 2, 2, projection='3d')
  20. # 生成子图 2 数据
  21. X = np.arange(-2, 2, 0.1)
  22. Y = np.arange(-2, 2, 0.1)
  23. X, Y = np.meshgrid(X, Y)
  24. Z = np.sqrt(X ** 2 + Y ** 2)
  25. # 绘制第 2 张图
  26. ax2.plot_surface(X, Y, Z, cmap=plt.cm.winter)
  27. # 显示图
  28. plt.show()

 

Python数据处理之Matplotlib学习

上面就是matplotlib的一些常用的用法了,记录在此也方便自己的查阅。

  • 微信公众号
  • 关注微信公众号
  • weinxin
  • QQ群
  • 我们的QQ群号
  • weinxin
王 茂南
  • 本文由 发表于 2018年4月30日20:03:22
  • 转载请务必保留本文链接:https://mathpretty.com/9311.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: