Matplotlib中Object-oriented方法绘图流程tutorial——基于官方文档案例

Matplotlib中一张plot的生态圈

官方文档链接:https://matplotlib.org/stable/tutorials/introductory/lifecycle.html
使用matplotlib完成一张图的开始、加工、结束。我们将从一些原始数据入手,并以保存一张自定义的可视化图片结束。在展示过程中,我们尽量突出一些整洁的功能,以及matplotlib使用的最佳练习方法。

Matplotlib有两种接口:Object-Oriented API, Pyplot

Object-Oriented方法
matplotlib有两种接口,第一种是面向对象接口。在这份案例中,我们将在一个figure.Figure实例中利用axex.Axes实例来完成可视化。
Pyplot方法
第二种方法是基于MATLAB和state-based的接口。他们都被封装在了pyplot模块中。更多详情见pyplot tutorials。
本文的多数内容都很直接,但有两个关键点需要记住:
1.Figure是最终的图像,它可能包含1个或多个Axes
2.Axes代表一个独立的plot(绘图),它不能与plot中的axis对象(代表plot中的x/y轴)混淆
在Axes上直接进行绘图的操作我们称之为方法,这些方法使我们绘出的图像更具灵活性,且更具个性。

原始数据

我们使用基于该教程衍生出的一张帖子内的数据,它包含一系列公司的销售信息。

import numpy as np
import matplotlib.pyplot as plt

data = {'Barton LLC': 109438.50,
        'Frami, Hills and Schmidt': 103569.59,
        'Fritsch, Russel and Anderson': 112214.71,
        'Jerde-Hilpert': 112591.43,
        'Keeling LLC': 100934.30,
        'Koepp Ltd': 103660.54,
        'Kulas Inc': 137351.96,
        'Trantow-Barrows': 123381.38,
        'White-Trantow': 135841.99,
        'Will LLC': 104437.60} #字典形式储存的键值数据
group_data = list(data.values()) #所有值构成的列表
group_names = list(data.keys()) #所有键组成的列表
group_mean = np.mean(group_data) #np库中对数组求均值的方法,list同样适用。

准备开始

这份数据天然适合用柱状图(barplot)可视化,每组一个柱棒。为了用object-oriented方法实现它,我们首先实例化一个figure.Figure和axes.Axes。这张Figure就像一个帆布(翻译成“画布”),Axes就是我们在画布上用来进行可视化展示的部分画布。

fig, ax = plt.subplots() #创建一个Figure和Axes

创建的Figure和Axes
Alt
现在我们有了实例化的Axes,我们可以在这上面画图了。

fig, ax = plt.subplots()
ax.barh(group_names, group_data) #在ax上绘制水平柱状图

在Axes上plot出的水平柱状图
Alt

控制绘图的风格

Matplotlib有许多可以使用的绘图风格,使得你能够根据自身需要修缮你的可视化结果。我们可以使用下列清单中的风格。

print(plt.style.available)
#Out:['Solarize_Light2', '_classic_test_patch', '_mpl-gallery', '_mpl-gallery-nogrid', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn', 'seaborn-bright', 'seaborn-colorblind', 'seaborn-dark', 'seaborn-dark-palette', 'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'tableau-colorblind10']

可以用下述方法适配一种风格。

plt.style.use('fivethirtyeight')

现在我们为上图重新标注了风格,再来看看它的样子。

fig, ax = plt.subplots()
ax.barh(group_names, group_data)

风格设置后的水平柱状图
Alt
绘图风格控制很多东西,比如颜色,线条宽度,背景颜色等。

自定义你的plot

现在我们已经有了大致想要的图片,让我们再微调一下它,从而达到输出的要求。首先,我们旋转x轴,为的是让它显示地更清楚。我们可以使用axes.Axes.get_xticklabels()方法获得这些x轴标签的控制权。

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels() #为ax的x轴标签命名(赋值)

如果我们想一次性设置许多不同的属性,使用*pyplot.setp()*函数会很有效率。它将接收一个或多个列表的matolotlib中的对象,并且尝试对列表中每个对象设置一些风格元素。

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')

x轴标签旋转后的图片
Alt

底部的标签看起来像被切掉了一些。我们可以让Matplotlib为figures中我们创造的元素自动腾出空间。为了实现这个目的,我们设置rcParams中的autolayout值。更多关于使用rcParams控制风格、布局,以及plot中其他特征的方法,请见官方文档。link:Customizing Matplotlib with style sheets and rcParams

plt.rcParams.update({'figure.autolayout': True})

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')

使用reParams转换风格后的图片显示效果,标签被完整的显示了出来。
alt
要通过object-oriented途经为plot各轴添加标签,可以用Artist.set()方法来设置这个Axes对象的属性。

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
       title='Company Revenue') #Axes.set方法全局设置ax的多个属性

在开始的plt.subplots()方法中,可以指定图像的尺寸

fig, ax = plt.subplots(figsize=(8, 4)) #指定图像比例大小
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
       title='Company Revenue')

设置尺寸比例后的图片明显美观
alt
------下面是稍微复杂的标签设置方法------
可以用函数形式指定自定义的标签格式。我们创建一个接收整数元素为输入,字符串返回值为输出的函数。当我们使用Axis.set_major_formatter 或者 Axis.set_minor_formatter时,它们会自动创建并使用一个ticker.FuncFormatter类。

def currency(x, pos):
    """The two arguments are the value and tick position"""
    if x >= 1e6:
        s = '${:1.1f}M'.format(x*1e-6)
    else:
        s = '${:1.0f}K'.format(x*1e-3)
    return s

这个函数中x是原始的刻度标签,pos是标签位置,我们在这里只使用x参数,但是这两个参数都是必要的。
我们可以把这个函数应用到我们图像的标签上。为了实现这个目标,我们使用axes的xaxis属性。这个方法能让我们在图像中特定的轴上进行操作。

fig, ax = plt.subplots(figsize=(6, 8))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')

ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
       title='Company Revenue')
ax.xaxis.set_major_formatter(currency) #函数作为一个对象,被传入方法的对应位置上。

在同一个axes.Axes实例上绘出多个元素是没问题的。我们可以在ax对象上调用其他绘图方法实现这一目的。

fig, ax = plt.subplots(figsize=(8, 8))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')

# Add a vertical line, here we set the style in the function call
ax.axvline(group_mean, ls='--', color='r')

# Annotate new companies
for group in [3, 5, 8]:
    ax.text(145000, group, "New Company", fontsize=10,
            verticalalignment="center")

# Now we move our title up since it's getting a little cramped
ax.title.set(y=1.05)

ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
       title='Company Revenue')
ax.xaxis.set_major_formatter(currency)
ax.set_xticks([0, 25e3, 50e3, 75e3, 100e3, 125e3])
fig.subplots_adjust(right=.1)

plt.show()

保存我们的图片

现在我们对图像已经比较满意了,是时候保存它了。Matplotlib中有多种文件保存格式,我们可以输入可供保存的形式。

print(fig.canvas.get_supported_filetypes())

对我们的figure使用savefig方法来保存图片,注意保存中有三个需要额外注意的参数:
transparent=True : makes the background of the saved figure transparent if the format supports it.

dpi=80 : controls the resolution (dots per square inch) of the output.

bbox_inches=“tight”: fits the bounds of the figure to our plot.
简而言之,上面三个参数的作用依次是:
1.设置被保存图片的透明背景,如果保存的格式支持此项操作的话。
2.控制输出图像中每英寸包含的点数,也就是清晰度。
3.让figure自适应我们plot的边框线,即防止出现边界显示不完整的情况。

2022_09_03_17_54

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值