打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

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

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

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

作者&编辑 | 汤兴旺

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

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

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等等,欢迎大家了解加入,我们一起攻破编程与开源框架。

转载文章请后台联系

侵权必究

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
matplotlib实现一页多图
Matplotlib数据可视化:三大容器对象与常用设置
Python中的Matplotlib绘图
Python绘图
直播案例 | Python 降维实践及在特征脸、图像重构和文本数据中的应用
超全的多子图(subplots)绘制技巧分享~~
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服