使用面向对象接口的matplotlib绘图与seaborn
我个人非常喜欢用面向对象的方式来使用 matplotlib
:
f, axarr = plt.subplots(2, sharex=True)
axarr[0].plot(...)
axarr[1].plot(...)
这样可以更方便地管理多个图形和子图。
问题是:如何用这种方式来使用 seaborn 呢?或者,怎么把 这个例子改成面向对象的风格?怎么告诉 seaborn
的绘图函数,比如 lmplot
,它应该绘制到哪个 Figure
或 Axes
上呢?
1 个回答
294
这要看你使用的是哪个seaborn的函数。
seaborn中的绘图函数大致可以分为两种类型:
- “坐标轴级”函数,比如
regplot
、boxplot
、kdeplot
等等 - “图形级”函数,比如
relplot
、catplot
、displot
、pairplot
、jointplot
以及一两个其他的
第一组函数的特点是需要一个明确的 ax
参数,并且返回一个 Axes
对象。正如这个名字所暗示的,你可以通过传递你的 Axes
来以“面向对象”的方式使用它们:
f, (ax1, ax2) = plt.subplots(2)
sns.regplot(x, y, ax=ax1)
sns.kdeplot(x, ax=ax2)
坐标轴级函数只会在一个 Axes
上绘图,不会对图形做其他的修改,所以它们可以在一个面向对象的matplotlib脚本中完美共存。
第二组函数(图形级)则是因为生成的图可能包含多个坐标轴,并且这些坐标轴总是以“有意义”的方式组织在一起。这意味着这些函数需要完全控制图形,所以你不能把一个 lmplot
绘制到已经存在的图上。调用这些函数时,总是会初始化一个图形,并为你要绘制的特定图形进行设置。
不过,一旦你调用了 lmplot
,它会返回一个 FacetGrid
类型的对象。这个对象有一些方法可以操作生成的图,并且了解图的结构。它还可以通过 FacetGrid.fig
和 FacetGrid.axes
参数访问底层的图形和坐标轴数组。jointplot
函数也很相似,但它使用的是 JointGrid
对象。因此,你仍然可以在面向对象的上下文中使用这些函数,但所有的自定义设置必须在你调用函数之后进行。