在Python中,如何继承和重写类实例上的方法,将这个新版本分配给与旧版本相同的名称?

在Python中,如何继承和重写类实例上的方法,将这个新版本分配给与旧版本相同的名称?,python,class,matplotlib,plot,instance,Python,Class,Matplotlib,Plot,Instance,在Matplotlib中,一个常见的问题是使用pcolor、pcolormesh和contourf绘制的面片对象之间不需要的白线。请参见前两个和后一个 我试图通过使用MethodType向Axis类/子类实例添加新方法来自动修复此问题。我这样做而不是子类化,只是因为我想通过将GridSpec对象的切片传递到地物实例上的add_子图方法来生成轴,我不知道如何使用子类matplotlib.Axes.subplot来实现这一点,但我欢迎您的建议。下面是一些示例代码: 从类型导入方法类型 将matplo

在Matplotlib中,一个常见的问题是使用pcolor、pcolormesh和contourf绘制的面片对象之间不需要的白线。请参见前两个和后一个

我试图通过使用MethodType向Axis类/子类实例添加新方法来自动修复此问题。我这样做而不是子类化,只是因为我想通过将GridSpec对象的切片传递到地物实例上的add_子图方法来生成轴,我不知道如何使用子类matplotlib.Axes.subplot来实现这一点,但我欢迎您的建议。下面是一些示例代码:

从类型导入方法类型 将matplotlib.pyplot作为plt导入 从matplotlib.gridspec导入gridspec f=plt.图 gs=网格规格2,1 ax=f.add_子图[0,0] def_pcolormeshself,*args,**kwargs: p=self.pcolormesh*args,**kwargs p、 设置边缘颜色“面” p、 设置_线宽0.2将覆盖白线,而不会使每个正方形的角点可见 返回p def _轮廓自我,*args,**kwargs: c=自身轮廓f*args,**kwargs 对于c.集合中的uu: _.设置颜色为“面部” 返回c ax.mypcolormesh=MethodType\u pcolormesh,ax ax.mycontourf=方法类型 在最后一行中,我希望能够编写ax.pcolormesh而不是ax.mypcolormesh,但这会引发递归错误,因为_pcolormesh调用原始方法名。。。现在它的别名为它自己


那么,如何访问此Axis实例上的方法、覆盖它并保留原始名称?

嗯。。。我差不多解决了。只用

ax.\u轮廓f=ax.contourf 保存旧方法的副本,然后

def _轮廓自我,*args,**kwargs: c=自身参数*args,**kwargs 对于c.集合中的uu: _.设置颜色为“面部” 返回c ax.contourf=MethodType_contourf,ax 它指定新方法调用旧方法的副本。

有效的解决方案 由于单独替换每个轴的方法比使用简单函数要复杂得多,因此最有效的方法是使用相应的函数创建一个Python文件myhacks.py

def pcolormesh(ax, *args, **kwargs):
    p = ax.pcolormesh(*args, **kwargs)
    p.set_edgecolor('face')
    p.set_linewidth(0.2)
    return p
并在需要pcolormesh的改进版本时使用它:

import matplotlib.pyplot as plt
import myhacks as m
# ...other imports

fig, ax = plt.subplots()
m.pcolormesh(ax, other_arguments)
这也适用于已经创建的文件,其中只需使用m.pcolormeshax搜索replace ax.pcolormesh,必要时使用regex搜索可能的其他轴名称

学术解决方案 当然,可以将matplotlib.axes.axes子类化以包含所需的功能。因为除了知道如何做之外,这并没有什么真正的好处,所以我称之为学术解决方案

同样,我们可以为自定义类创建一个文件myhacks.py,将自定义类注册为Matplotlib的投影

from matplotlib.axes import Axes
from matplotlib.projections import register_projection

class MyAxes(Axes):
    name = 'mycoolnewaxes'
    def pcolormesh(self,*args, **kwargs):
        p = Axes.pcolormesh(self,*args, **kwargs)
        p.set_edgecolor('face')
        p.set_linewidth(0.2)
        return p

register_projection(MyAxes)
并通过导入它并使用投影创建轴来使用它:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
import myhacks as m

fig = plt.figure()
gs = GridSpec(2,1)
ax = fig.add_subplot(gs[0,0], projection='mycoolnewaxes')

z = np.random.rand(10,13)
ax.pcolormesh(z)

plt.show()

原来问题的修正是2行,为了使修正更容易,你增加了6行?!对我来说似乎没有什么意义。我只是不喜欢一百万次地复制和粘贴两行。我得搞很多阴谋。这6行进入一个自动构建子地块结构的函数,所以我真的需要添加6行,以避免在剩下的研究生课程中键入2行1000次。对这种方法给出了清晰的解释。