Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 可滚动的Matplotlib图形无法从函数运行_Python_Function_Matplotlib_Jupyter_Spyder - Fatal编程技术网

Python 可滚动的Matplotlib图形无法从函数运行

Python 可滚动的Matplotlib图形无法从函数运行,python,function,matplotlib,jupyter,spyder,Python,Function,Matplotlib,Jupyter,Spyder,我目前正在处理医学图像,并编写代码准备培训集。 为此,我需要滚动卷数据的各个部分 我的主IDE是Spyder,但IndexTracker对象的标准实现在函数中不适用于我 def ShowSlice(): fig, ax = plt.subplots(1, 1) X = np.random.rand(20, 20, 40) tracker = IndexTracker(ax, X) fig.canvas.mpl_connect('scroll_event', tra

我目前正在处理医学图像,并编写代码准备培训集。 为此,我需要滚动卷数据的各个部分

我的主IDE是Spyder,但IndexTracker对象的标准实现在函数中不适用于我

def ShowSlice():
    fig, ax = plt.subplots(1, 1)
    X = np.random.rand(20, 20, 40)
    tracker = IndexTracker(ax, X)
    fig.canvas.mpl_connect('scroll_event', tracker.on_scroll)
    plt.show()
    return tracker
    
# ShowSlice()  # Does not works    
tr = ShowSlice()  # Works
这个标准实现对我来说很有用:

但一旦我将绘图的创建放入函数中,创建的绘图就不再可滚动:

import numpy as np
import matplotlib
matplotlib.use('Qt5Agg')
import matplotlib.pyplot as plt

class IndexTracker(object):
    def __init__(self, ax, X):
        self.ax = ax
        ax.set_title('use scroll wheel to navigate images')

        self.X = X
        rows, cols, self.slices = X.shape
        self.ind = self.slices//2

        self.im = ax.imshow(self.X[:, :, self.ind])
        self.update()

    def onscroll(self, event):
        print("%s %s" % (event.button, event.step))
        if event.button == 'up':
            self.ind = (self.ind + 1) % self.slices
        else:
            self.ind = (self.ind - 1) % self.slices
        self.update()

    def update(self):
        self.im.set_data(self.X[:, :, self.ind])
        self.ax.set_ylabel('slice %s' % self.ind)
        self.im.axes.figure.canvas.draw()

def plot(X):
    fig, ax = plt.subplots(1, 1)
    tracker = IndexTracker(ax, X)
    fig.canvas.mpl_connect('scroll_event', tracker.onscroll)
    plt.show()

plot(np.random.rand(200, 200, 500))

有什么问题吗?如何从函数中创建可滚动绘图?

我自己解决了这个问题: 问题是matplotlib无法正确识别plot实例,因此必须在函数中设置它。 基本的、非普遍的或实际的应用如下:

figList,axList=[],[]
def plotSlices(image, view):
    fig, ax = plt.subplots(1, 1)
    figList.append(fig)
    axList.append(ax)
    axList[-1].set_title(view)
    tracker = IndexTracker(axList[-1], image)
    figList[-1].canvas.mpl_connect('scroll_event', tracker.onscroll)
    plt.show(figList[-1],block=False)
其中numpy数组与图像的透视图一起读取。这仅用于标题,因此您可以将其删除/硬编码标题。 fig和ax对象被附加到各自的列表中,其中只有最后添加的元素被提供给matplotlib进行打印

这样,在函数中定义的图之间滚动即可工作。 一个问题是,我显然重载了.show()方法,该方法应该只接受block=False/True参数,但实际上确实正确标识了正确的绘图,如下所示: plt.show(图,块=假)
它在处理这个问题时抛出了一个错误,但最终还是有效的。太好了

我自己解决了这个问题: 问题是matplotlib无法正确识别plot实例,因此必须在函数中设置它。 基本的、非普遍的或实际的应用如下:

figList,axList=[],[]
def plotSlices(image, view):
    fig, ax = plt.subplots(1, 1)
    figList.append(fig)
    axList.append(ax)
    axList[-1].set_title(view)
    tracker = IndexTracker(axList[-1], image)
    figList[-1].canvas.mpl_connect('scroll_event', tracker.onscroll)
    plt.show(figList[-1],block=False)
其中numpy数组与图像的透视图一起读取。这仅用于标题,因此您可以将其删除/硬编码标题。 fig和ax对象被附加到各自的列表中,其中只有最后添加的元素被提供给matplotlib进行打印

这样,在函数中定义的图之间滚动即可工作。 一个问题是,我显然重载了.show()方法,该方法应该只接受block=False/True参数,但实际上确实正确标识了正确的绘图,如下所示: plt.show(图,块=假) 它在处理这个问题时抛出了一个错误,但最终还是有效的。太好了

简短回答 以更简洁的方式,您应该在主上下文中保持对跟踪器实例的访问。否则,此跟踪器将在函数结束时销毁

def ShowSlice():
    fig, ax = plt.subplots(1, 1)
    X = np.random.rand(20, 20, 40)
    tracker = IndexTracker(ax, X)
    fig.canvas.mpl_connect('scroll_event', tracker.on_scroll)
    plt.show()
    return tracker
    
# ShowSlice()  # Does not works    
tr = ShowSlice()  # Works
下面是我已经修改过的官方示例,将情节封装在函数中

def ShowSlice():
    fig, ax = plt.subplots(1, 1)
    X = np.random.rand(20, 20, 40)
    tracker = IndexTracker(ax, X)
    fig.canvas.mpl_connect('scroll_event', tracker.on_scroll)
    plt.show()
    return tracker
    
# ShowSlice()  # Does not works    
tr = ShowSlice()  # Works
我的调查 谢谢你的问题,那正是我目前的问题。你自己的回答帮助我找到这种行为的真正原因

您提出的解决方案强调了了解至少与图形或轴相关的某些变量的问题

我已经遇到了类似的问题,matplotlib中的动画。这个问题的解决方案是在主上下文中保留动画实例,如以下示例所示: ,即使未使用动画对象(
line_ani
im_ani
),也必须将其保存在内存中

这里的问题似乎与tracker实例完全相同

深入阅读
mpl\u connect
文档,确认:

FigureCanvasBase.mpl_connect方法返回一个连接id(一个 整数),可用于通过断开回调

注意

画布只保留对用作实例的实例方法的弱引用 回调。因此,您需要保留对实例的引用 拥有这样的方法。否则实例将被垃圾收集 回调将消失。这不影响使用的自由函数 作为回调

感谢您的阅读。

简短回答 以更简洁的方式,您应该在主上下文中保持对跟踪器实例的访问。否则,此跟踪器将在函数结束时销毁

def ShowSlice():
    fig, ax = plt.subplots(1, 1)
    X = np.random.rand(20, 20, 40)
    tracker = IndexTracker(ax, X)
    fig.canvas.mpl_connect('scroll_event', tracker.on_scroll)
    plt.show()
    return tracker
    
# ShowSlice()  # Does not works    
tr = ShowSlice()  # Works
下面是我已经修改过的官方示例,将情节封装在函数中

def ShowSlice():
    fig, ax = plt.subplots(1, 1)
    X = np.random.rand(20, 20, 40)
    tracker = IndexTracker(ax, X)
    fig.canvas.mpl_connect('scroll_event', tracker.on_scroll)
    plt.show()
    return tracker
    
# ShowSlice()  # Does not works    
tr = ShowSlice()  # Works
我的调查 谢谢你的问题,那正是我目前的问题。你自己的回答帮助我找到这种行为的真正原因

您提出的解决方案强调了了解至少与图形或轴相关的某些变量的问题

我已经遇到了类似的问题,matplotlib中的动画。这个问题的解决方案是在主上下文中保留动画实例,如以下示例所示: ,即使未使用动画对象(
line_ani
im_ani
),也必须将其保存在内存中

这里的问题似乎与tracker实例完全相同

深入阅读
mpl\u connect
文档,确认:

FigureCanvasBase.mpl_connect方法返回一个连接id(一个 整数),可用于通过断开回调

注意

画布只保留对用作实例的实例方法的弱引用 回调。因此,您需要保留对实例的引用 拥有这样的方法。否则实例将被垃圾收集 回调将消失。这不影响使用的自由函数 作为回调

谢谢你的阅读