【问题标题】:matplotlib colorbar not working (due to garbage collection?)matplotlib colorbar 不工作(由于垃圾收集?)
【发布时间】:2023-12-18 05:55:02
【问题描述】:

我有一个类似这个的绘图功能

def fct():
    f=figure()
    ax=f.add_subplot(111)
    x,y=mgrid[0:5,0:5]
    z=sin(x**2+y**2)
    ax.pcolormesh(x,y,z)

当我在ipython中定义了上面的函数(使用--pylab选项),然后调用

fct()
colorbar()

我收到一个错误

“RuntimeError: 找不到可用于创建颜色条的可映射对象。”。

def fct():
    f=figure()
    x,y=mgrid[0:5,0:5]
    z=sin(x**2+y**2)
    pcolormesh(x,y,z)

然后就可以了。我想这与垃圾收集有关 - 在第一个示例中如何防止此问题?

【问题讨论】:

标签: python matplotlib garbage-collection ipython


【解决方案1】:

这是因为您的第一个示例,您使用的是ax.polormesh,而不是pyplot.polotmesh(由pylab 导入的命名空间),当您调用colorbar()(实际上是plt.colorbar())时,它忘记了哪个可映射和它应该制作颜色条的斧头。

因此添加这些行将使其工作:

import matplotlib.pyplot as plt
fct()
ax=plt.gca() #get the current axes
PCM=ax.get_children()[2] #get the mappable, the 1st and the 2nd are the x and y axes
plt.colorbar(PCM, ax=ax) 

现在您提到您的实际情节要复杂得多。您想确保它是 ax.get_children()[2],或者您可以通过查找 matplotlib.collections.QuadMesh 实例来选择它。

【讨论】:

  • 在我的情况下,情节更复杂,要找到我必须做的正确孩子:for PCM in ax.get_children(): if type(PCM) == matplotlib.image.AxesImage: break
【解决方案2】:

我认为这更多地与pylab 状态机和作用域有关。

更好的做法是执行以下操作(显式优于隐式):

import numpy as np
import matplotlib.pyplot as plt

def fct():
    f = plt.figure()
    ax = f.add_subplot(111)
    x, y = np.mgrid[0:5,0:5]
    z = np.sin(x**2+y**2)
    mesh = ax.pcolormesh(x, y ,z)

    return ax, mesh

ax, mesh = fct()
plt.colorbar(mesh, ax=ax)

【讨论】:

    【解决方案3】:

    你的函数非常小并且没有参数,所以你真的需要将绘图包装在一个函数中吗?怎么样:

    import numpy as np
    import matplotlib.pyplot as plt
    
    fig, ax = plt.subplots(1, 1)
    x, y = np.mgrid[0:5,0:5]
    z = np.sin(x**2+y**2)
    mesh = ax.pcolormesh(x, y ,z)
    fig.colorbar(mesh)
    plt.show()
    

    【讨论】:

    • 我的函数只是一个最小的工作示例。实际的绘图函数要复杂得多,而且会被反复调用,所以我只想写一次。
    【解决方案4】:

    对我来说,以下代码不起作用

    PCM=ax.get_children()[2] 
    plt.colorbar(PCM, ax=ax)
    

    由于我的情节有点复杂,我不得不根据@lib 的评论使用以下代码。

    ax=plt.gca() #get the current axes
    for PCM in ax.get_children():
        if isinstance(PCM, mpl.cm.ScalarMappable):
            break
            
    plt.colorbar(PCM, ax=ax)
    

    【讨论】:

      最近更新 更多