前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >matplotlib使用教程(一):基础概念

matplotlib使用教程(一):基础概念

原创
作者头像
云时之间
修改2020-11-10 14:33:44
3710
修改2020-11-10 14:33:44
举报
文章被收录于专栏:云时之间

这一系列文章原载于公众号 工程师milter,如果文章对大家有帮助,恳请大家动手关注下哈~


matplotlib是优秀的python画图工具,功能十分强大,但是使用却很复杂。你有没有如下的经历:

1、图形只差一点点就满足你的要求,可是怎么调 也调不到位

2、好不容易从stackoverflow上查到一个解决方案 ,可使用时却各种调整无法达到预期,或者好不容易搞定了。随便换个图又不好使了

3、网上一下查到好几个方案,不知道到底哪个好,只能一个一个试

4、有时候,想要调整一个地方,可是不知道怎么搜索关键字

如果你有过以上的经历,恭喜,这个教程就是为你量身定做的。这个教程和其他教程有啥区别?答案是:这个教程是从架构的高度来讲解matplotlib的,学完后,你不只是知道了怎么使用matplotlib,更是知道为什么要这样使用。当你脑子中有一个图的模样时,你知道如何组合不同的matplotlib的功能来实现它。

一:matplotlib的编程范式

matplotlib同时支持过程式和面向对象式的使用方法。也就是同一个效果,大部分情况下都有至少两种方法实现。这给初学者造成了很多困惑。所以,我们要先了解这两种方式。

首先看一下过程式的方法:

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt

def f(t):
    return np.exp(-t) * np.cos(2*np.pi*t)
t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)
plt.figure(1)
plt.subplot(211)
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')
plt.subplot(212)
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.show()

这段代码的效果如下:

这种风格是典型的matlab风格,也叫基于状态的绘制方法。

另一种就是官方推荐的面向对象的绘制方法。上面的图,用面向对象来写,就是这样的:3

代码语言:javascript
复制
def f(t):
    return np.exp(-t) * np.cos(2*np.pi*t)
t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)
fig, (ax1, ax2) = plt.subplots(2,1)


ax1.plot(t1, f(t1), 'bo', t2, f(t2), 'k')

ax2.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.show()

这种风格的好处是绘制对象非常明确。我们这门课程主要是用面向对象的风格,这个也符合matplotlib的最佳实践!

二:figure

matplotlib中最大的概念就是figure,一个figure就是一幅图,可以把它理解成一个有大小的画布。

那么,下面的问题自然是:如何获得一个figure?如何在figure上画图?首先,我们来看看获得一个figure的办法:

代码语言:javascript
复制
fig = plt.figure()

这样就获得了一个figure。在解决如何在figure上画图之前,我们先来观察一下这个fig。既然figure是画布,那么大小如何设置呢?可以这样来设置:

代码语言:javascript
复制
fig.set_figheight(100)
fig.set_figwidth(100)

看起来比较直观,但是这里有个巨坑的地方,就是里面的100代表的是英寸!!!如果我想要一个(1200,600)像素的图,该怎么办呢?要达成目标,我们必须了解figure的另一个属性:dpi(dot per inch)。它代表的是每英寸有多少个像素点。默认值是72。我们可以使用如下的三种设置中的一种得到(1200,600)像素的图:

代码语言:javascript
复制
# figsize=(宽,高)
figsize=(15,7.5), dpi= 80
figsize=(12,6)  , dpi=100
figsize=( 8,4)  , dpi=150

看,光是得到一个大小确定的figure就这么麻烦。但这正是matplotlib厉害的地方,高度的可定制性。seaborn等绘图库都只是对matplotlib的封装而已。学会matplotlib,其他的绘图库可以很快学会。

既然fig代表一幅图,如果我们还想继续画一幅图怎么办呢?看如下代码:

代码语言:javascript
复制
fig1 = plt.figure()
fig2 = plt.figure()

这里,fig1和fig2代表两个不同的图,这可以通过它们的number属性看出来:

matplotlib内部维护着一个全局的计数,记录了一共创建了多少个figure。

现在我们来总整体上看看figure有哪些属性,执行fig.__dict__可以得到如下内容:

代码语言:javascript
复制
{'_stale': True,
 'stale_callback': None,
 'figure': None,
 '_transform': None,
 '_transformSet': False,
 '_visible': True,
 '_animated': False,
 '_alpha': None,
 'clipbox': None,
 '_clippath': None,
 '_clipon': True,
 '_label': '',
 '_picker': None,
 '_contains': None,
 '_rasterized': None,
 '_agg_filter': None,
 '_mouseover': False,
 'eventson': False,
 '_oid': 0,
 '_propobservers': {},
 '_remove_method': None,
 '_url': None,
 '_gid': None,
 '_snap': None,
 '_sketch': None,
 '_path_effects': [],
 '_sticky_edges': _XYPair(x=[], y=[]),
 '_in_layout': True,
 'callbacks': <matplotlib.cbook.CallbackRegistry at 0x7f75632e4410>,
 'bbox_inches': Bbox([[0.0, 0.0], [6.0, 4.0]]),
 'dpi_scale_trans': <matplotlib.transforms.Affine2D at 0x7f75655edc90>,
 '_dpi': 72.0,
 'bbox': <matplotlib.transforms.TransformedBbox at 0x7f75655ed0d0>,
 'transFigure': <matplotlib.transforms.BboxTransformTo at 0x7f75655ed090>,
 'patch': <matplotlib.patches.Rectangle at 0x7f7563004310>,
 'canvas': <matplotlib.backends.backend_agg.FigureCanvasAgg at 0x7f75632e4e10>,
 '_suptitle': None,
 'subplotpars': <matplotlib.figure.SubplotParams at 0x7f75632e4e50>,
 '_layoutbox': None,
 '_constrained_layout_pads': {'w_pad': 0.04167,
  'h_pad': 0.04167,
  'wspace': 0.02,
  'hspace': 0.02},
 '_constrained': False,
 '_tight': False,
 '_tight_parameters': {},
 '_axstack': <matplotlib.figure.AxesStack at 0x7f75632e4ed0>,
 'suppressComposite': None,
 'artists': [],
 'lines': [],
 'patches': [],
 'texts': [],
 'images': [],
 'legends': [],
 '_axobservers': [<function matplotlib.backend_bases.FigureManagerBase.__init__.<locals>.notify_axes_change(fig)>],
 '_cachedRenderer': None,
 '_align_xlabel_grp': <matplotlib.cbook.Grouper at 0x7f75655edd90>,
 '_align_ylabel_grp': <matplotlib.cbook.Grouper at 0x7f75632e4090>,
 '_gridspecs': [],
 'number': 1}

属性非常多,主要分为两类,一类是对figure的设置,比如wspace、hspace等。另一类是和figure中画的内容有关,比如lines、texts、legends、artists等。

此时不需要理解全部的属性,只要浏览一遍,有个大致的印象就可以了。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档