专栏首页有三AI【Python进阶】带你使用Matplotlib进行可视化

【Python进阶】带你使用Matplotlib进行可视化

欢迎来到专栏《Python进阶》。在这个专栏中,我们会讲述Python的各种进阶操作,包括Python对文件、数据的处理,Python各种好用的库如NumPy、Scipy、Matplotlib、Pandas的使用等等。我们的初心就是带大家更好的掌握Python这门语言,让它能为我所用。

今天是《Python进阶》专栏的第五期,在本期中,我们将主要介绍如何使用Matplotlib这个第三方库进行数据可视化。

作者&编辑 | 汤兴旺

“美丽的可视化可反映出所描述数据的品质,显式地揭示出源数据中内在和隐式的属性和关系,读者了解了这些属性和关系之后,可以因此而获取新的知识、洞察力和乐趣。”

以上是书籍《数据可视化之美》对可视化的解读。说的很有道理,相信大家听说过“一图胜千言”这句话,当看到一堆数据时,若你对数字不够敏感,肯定会费劲半天找不到规律,但若用一张图来表达时,相信你一定会一目了然。下面我就大家使用Matplotlib对数据进行美丽的可视化。

1 Matplotlib 的基本操作

在Matplotlib中有三个基本概念,分别是Figure、axes和axis。

下面我来详细解释下这三个基本概念。在Matplotlib中,figure你可以理解成一个画布或者一个窗口,axes是指画布上的一个区域,你画的图就在这个区域上。你可以把figure看成一张白纸,在纸上的任何区域画图,确定画图区域并确定作图的一些方式的东西的就是axes,即坐标对象(坐标系)。

由于在一张白纸上可以有几个区域进行画图,另外画图区域必须存在于白纸上才有意义。因此在figure上可有多个axes,axes必在figure上,要画图必有axes。

另外axis就是我们平时常见的坐标轴,如x轴、y轴等。

对于上面的概念我们可以用下图进行直观理解。

通过上面的讲解,我们知道在Matplotlib中的图像都位于figure画布中,因此可以使用plt.figure创建一个新画布。如果要在一个图表中绘制多个子图,可使用subplot。

话不多说,我们直接看下面代码:

import matplotlib.pyplot as plt import numpy as np from numpy.random import randn fig = plt.figure() # 创建一个新的 Figure ax1 = fig.add_subplot(2, 2, 1) # 不能通过空 Figure 绘图,必须用 add_subplot 创建一个或多个 subplot 才行 ax2 = fig.add_subplot(2, 2, 2) ax3 = fig.add_subplot(2, 2, 3)

ax4 = fig.add_subplot(2, 2, 4) plt.plot(randn(50).cumsum(),'k--') # 这条没有指定具体 subplot 的绘图命令会在最后一个用过的 subplot 上进行绘制 _ = ax1.hist(randn(100), bins=20, color='k', alpha=0.3) ax2.scatter(np.arange(30), np.arange(30) + 3*randn(30))

首先,创建了一个figure,然后在这个figure上画了四个区域,即四个子图,分别是直方图、三点图、折线图,还有一个是只有坐标轴的图。

如果我想要画多个figure应该怎么办呢?实际上如果要同时绘制多个图表,可以给figure()传递一个整数参数指定figure对象的序号。如下例所示:

import matplotlib.pyplot as plt

import numpy as np

plt.figure(1) # 创建图表1

plt.figure(2) # 创建图表2

ax1 = plt.subplot(211) # 在图表2中创建子图1

ax2 = plt.subplot(212) # 在图表2中创建子图2

x = np.linspace(0, 3, 100)

for i in range(5):

plt.figure(1) # 选择图表1

plt.plot(x, np.exp(i * x / 3))

plt.sca(ax1) # 选择图表2的子图1

plt.plot(x, np.sin(i * x))

plt.sca(ax2) # 选择图表2的子图2

plt.plot(x, np.cos(i * x))

plt.show()

执行完上面代码后,如下图。

2 Matplotlib的进阶操作

在1中的两个示例中,我们会发现手动创建figure,都使用了plt.figure()。如果没有plt.figure()可以吗?请看下面的示例:

import matplotlib.pyplot as plt

import numpy as np

x = np.linspace(-np.pi, 5*np.pi, num = 100)

y = np.sin(x)

plt.plot(x,y)

plt.show()

我们会发现这段代码中,没有plt.figure()也画出了图,WHY?难道前面误导了大家?我在前面说过,若没有figure就没有axes!

当然这个锅我不背,实际上这里plt.plot()是通过plt.gca()获得当前axes对象的ax,如果没有会自动创建一个,可以理解为就是figure。然后再调用ax.plot方法实现真正的绘图。

Matplotlib实际上是一套面向对象的绘图库,它所绘制的图表中每个图表元素,如线条 Line2D、文字Text、刻度等在内存中都有一个对象与之对应。为将面向对象的绘图库包装成只使用函数的调用接口,pyplot模块内部保存了当前图表以及当前子图等信息。当前的图表和子图可以使用plt.gcf()plt.gca()获得,分别表示"Get Current Figure"和"Get Current Axes"。在pyplot模块中,许多函数都是对当前的figure或axes对象进行处理,比如说:

plt.plot()实际上会通过plt.gca()获得当前的axes对象ax,然后再调用ax.plot()方法实现真正绘图。

2.1 对图进行装扮

上面3个示例中均没有展示图例、标注等,下面我们通过下面的示例来分享如何对一个图进行装扮。

import matplotlib.pyplot as plt

import numpy as np

fig, ax1 = plt.subplots(figsize=(8, 4))

r = np.linspace(0, 10, 100)

a = 4 * np.pi * r ** 2 # area

v = (4 * np.pi / 3) * r ** 3 # volume

ax1.set_title("surface area and volume of a sphere", fontsize=16)

ax1.set_xlabel("radius [m]", fontsize=16)

ax1.plot(r, a, lw=2, color="blue")

ax1.set_ylabel(r"surface area ($m^2$)", fontsize=16, color="blue")

for label in ax1.get_yticklabels():

label.set_color("blue")

ax2 = ax1.twinx()

ax2.plot(r, v, lw=2, color="red")

ax2.set_ylabel(r"volume ($m^3$)", fontsize=16, color="red")

for label in ax2.get_yticklabels():

label.set_color("red")

fig.tight_layout()

plt.show()

在上面的示例中我们通过set.title()设置了图的标题,通过set_xlabel和set_ylabel设置了y轴的标签,另外也通过get_yticklabels()和get_xticklabels()设置了坐标轴上刻度的不同的属性。

2.2、对图的某个细节进行放大

平时我们在处理图的时候,有时候需要对图的局部细节进行查看,这时候就需要对细节进行放大,对于这个问题该怎么解决呢?请看下面的案例:

import matplotlib.pyplot as plt import numpy as np import matplotlib as mpl fig = plt.figure(figsize=(8, 4)) def f(x): return 1 / (1 + x ** 2) + 0.1 / (1 + ((3 - x) / 0.1) ** 2) def plot_and_format_axes(ax, x, f, fontsize): ax.plot(x, f(x), linewidth=2) ax.xaxis.set_major_locator(mpl.ticker.MaxNLocator(5)) ax.yaxis.set_major_locator(mpl.ticker.MaxNLocator(4)) ax.set_xlabel(r"$x$", fontsize=fontsize) ax.set_ylabel(r"$f(x)$", fontsize=fontsize) ax = fig.add_axes([0.1, 0.15, 0.8, 0.8], facecolor="#f5f5f5") x = np.linspace(-4, 14, 1000) plot_and_format_axes(ax, x, f, 18) plt.show()

如果我想要对上图的横纵标在4附近的局部峰值进行放大查看,即下图圈红部分进行放大查看,应该如何操作呢?

代码如下:

import matplotlib.pyplot as plt

import numpy as np

import matplotlib as mpl

fig = plt.figure(figsize=(8, 4))

def f(x):

return 1 / (1 + x ** 2) + 0.1 / (1 + ((3 - x) / 0.1) ** 2)

def plot_and_format_axes(ax, x, f, fontsize):

ax.plot(x, f(x), linewidth=2)

ax.xaxis.set_major_locator(mpl.ticker.MaxNLocator(5))

ax.yaxis.set_major_locator(mpl.ticker.MaxNLocator(4))

ax.set_xlabel(r"$x$", fontsize=fontsize)

ax.set_ylabel(r"$f(x)$", fontsize=fontsize)

ax = fig.add_axes([0.1, 0.15, 0.8, 0.8], facecolor="#f5f5f5")

x = np.linspace(-4, 14, 1000)

plot_and_format_axes(ax, x, f, 18)

x0, x1 = 2.5, 3.5

ax = fig.add_axes([0.5, 0.5, 0.38, 0.42], facecolor='none')

x = np.linspace(x0, x1, 1000)

plot_and_format_axes(ax, x, f, 14)

plt.show()

代码区红色部分即实现放大部分的代码。实际是添加了另外一个axes,只不过这个axes包含在主图的axes中。

总结

本期我们介绍了Matplotlib中的一些应用,希望您能借助这个工具画出精美的图表。

下期预告:Python库Pandas的高级应用

知识星球推荐

有三AI编程与开源框架知识星球由我亲自维护,内设caffe实战,Python实战,Python每日一练,Pytorch实战、C++每一一练等板块。近期我重点更新caffe的实战教程,包括模型定义、数据处理、源码解读、定制自己的caffe等等,欢迎大家了解加入,我们一起攻破编程与开源框架。

转载文章请后台联系

侵权必究

本文分享自微信公众号 - 有三AI(yanyousan_ai),作者:汤兴旺

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【NLP-词向量】从模型结构到损失函数详解word2vec

    上周我们讲到,在进行NNLM训练时,能够得到副产品,词向量。本文介绍一种专门用于词向量制备的方法:word2vec,利用它能够高效的训练出词向量。

    用户1508658
  • 【GAN优化】详解SNGAN(频谱归一化GAN)

    今天将和大家一起学习具有很高知名度的SNGAN。之前提出的WGAN虽然性能优越,但是留下一个难以解决的1-Lipschitz问题,SNGAN便是解决该问题的一个...

    用户1508658
  • 【darknet速成】Darknet图像分类从模型自定义到测试

    GitHub: https://github.com/pjreddie/darknet

    用户1508658
  • python 数据可视化工具包 matplotlib

    ps: 在 jupyter notebook 环境需要添加 %matplotlib inline ,使得绘图生成在 notebook 页面。其他环境需要去掉 %...

    我是一条小青蛇
  • 核心网的演进(RCAF,PFDF和TSSF)——3GPP REST接口

    回首技术发展的多样性,从3GPP Release 13开始,标准已经走上了一条新路。更关注新的网络元素,广泛关注机器类型通信(MTC)、新的基于REST的接口(...

    SDNLAB
  • Hiredis源码阅读(二)

    上一篇介绍了Hiredis中的同步api以及回复解析api,这里紧接着介绍异步api。异步api需要与事件库(libevent、libev、ae一起工作)。

    chain
  • Demoo – 为移动端方案设计演示而生 - 腾讯ISUX

    腾讯ISUX
  • python | 工作笔记 | pandas 常用总结

    参考网址: http://pandas.pydata.org/pandas-docs/stable/merging.html

    努力在北京混出人样
  • python | 工作笔记 | pandas 常用总结

    努力在北京混出人样
  • 「事件驱动架构」事件溯源,CQRS,流处理和Kafka之间的多角关系

    事件溯源作为一种应用程序体系结构模式越来越流行。事件源涉及将应用程序进行的状态更改建模为事件的不可变序列或“日志”。事件源不是在现场修改应用程序的状态,而是将触...

    首席架构师智库

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动