matplotlib中的子类轴

时间:2018-02-03 01:42:08

标签: python-3.x matplotlib

标题几乎说明了。 但是,matplotlib的设置方式,无法简单地从Axes继承并使其有效。 Axes对象永远不会直接使用,通常只会从调用subplot或其他函数返回。

我想做这个有几个原因。 首先,一遍又一遍地减少具有相似参数的再现图。 像这样:

class LogTemp(plt.Axes):
    """ Axes to display temperature over time, in logscale """
    def __init__(self, *args, **kwargs):
        super.__init__(*args, **kwargs)
        self.set_xlabel("Time (s)")
        self.set_ylabel("Temperature(C)")
        self.set_yscale('log')

为此编写自定义函数并不困难,尽管它不会那么灵活。 更大的原因是我想要覆盖一些默认行为。 作为一个非常简单的例子,请考虑

class Negative(plt.Axes):
     """ Plots negative of arguments """
     def plot(self, x, y, *args, **kwargs):
         super().plot(x, -y, *args, **kwargs)

class Outliers(plt.Axes):
     """ Highlight outliers in plotted data """
     def plot(self, x, y, **kwargs):
         out = y > 3*y.std()
         super().plot(x, -y, **kwargs)
         super().plot(x[out], y[out], marker='x', linestyle='', **kwargs)       

如果使用函数,尝试修改多个行为方面将很快变得混乱。

但是,我还没有办法让matplotlib轻松处理新的Axes课程。 文档在我看过的任何地方都没有提到它。 This问题地址继承自Figure类。 然后可以将自定义类传递到某些matplotlib函数中。 一个悬而未决的问题here表明Axes并不是那么简单。

更新:可以使用补丁matplotlib.axes.Axes来覆盖默认行为,但这只能在程序首次执行时执行一次。使用此方法无法使用多个自定义Axes

1 个答案:

答案 0 :(得分:3)

我在github上找到了一个很好的方法。 他们的目标是Axes没有刻度或标记的对象,这大大加快了创建时间。 可以使用matplotlib注册“投影”,然后使用这些投影。

对于我给出的例子,可以通过

完成
class Outliers(plt.Axes):
    """ Highlight outliers in plotted data """
    name = 'outliers'
    def plot(self, x, y, **kwargs):
         out = abs(y - y.mean()) > 3*y.std()
         super().plot(x, y, **kwargs)
         super().plot(x[out], y[out], marker='x', linestyle='', **kwargs)

import matplotlib.projections as proj
proj.register_projection(Outliers)

然后它可以被

使用
ax = f.add_subplot(1, 1, 1, projection='outliers')

fig, axes = plt.subplots(20,20, subplot_kw=dict(projection='outliers'))

所需的唯一更改是类定义中的name变量,然后将该名称传递给子图的projection参数。