Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.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.figure.figure的行为与matplotlib.pyplot.figure如此不同_Python_Matplotlib_Tkinter - Fatal编程技术网

Python 为什么matplotlib.figure.figure的行为与matplotlib.pyplot.figure如此不同

Python 为什么matplotlib.figure.figure的行为与matplotlib.pyplot.figure如此不同,python,matplotlib,tkinter,Python,Matplotlib,Tkinter,一位程序员同事提醒我matplotlib.pyplot和Tkinter在一起表现不好的问题,如这个问题所示 我们对代码进行了更改,以防止相关问题中提到的潜在问题,具体如下: 旧的 import matplotlib.pyplot as plt self.fig = plt.figure(figsize=(8,6)) if os.path.isfile('./UI.png'): image = plt.imread('./UI.png') plt.axis('off') p

一位程序员同事提醒我matplotlib.pyplot和Tkinter在一起表现不好的问题,如这个问题所示

我们对代码进行了更改,以防止相关问题中提到的潜在问题,具体如下:

旧的

import matplotlib.pyplot as plt
self.fig = plt.figure(figsize=(8,6))
if os.path.isfile('./UI.png'):
    image = plt.imread('./UI.png')
    plt.axis('off')
    plt.tight_layout()
    im = plt.imshow(image)
# The Canvas
self.canvas = FigureCanvasTkAgg(self.fig, master = master)
self.toolbar = NavigationToolbar2TkAgg(self.canvas, root)
self.canvas.get_tk_widget().pack(fill=BOTH,expand=YES)
self.canvas.draw()
中级(未显示UI.png)

更改后的代码不再显示“背景”图像,我一直在尝试随机操作(因为我完全不知道这两个选项之间的差异),以使图形再次显示。更改涉及从
紧密布局
切换到
设置紧密布局
,以避免出现警告,如上所述。生成的代码如下所示:

潜在修复

import matplotlib.pyplot as plt
import matplotlib
self.fig = matplotlib.figure.Figure(figsize=(8, 6))
background_image = self.fig.add_subplot(111)
if os.path.isfile('./UI.png'):
    image = matplotlib.image.imread('./UI.png')
    background_image.axis('off')
    #self.fig.tight_layout() # This throws a warning and falls back to Agg renderer, 'avoided' by using the line below this one.
    self.fig.set_tight_layout(True)
    background_image.imshow(image)
# The Canvas
self.canvas = FigureCanvasTkAgg(self.fig, master=master)
self.toolbar = NavigationToolbar2TkAgg(self.canvas, root)
self.canvas.get_tk_widget().pack(fill=BOTH, expand=YES)
self.canvas.draw()
因此,问题是,为什么我们现在需要使用子图(使用matplotlib.figure.figure),而以前不需要(使用matplotlib.pyplot)

PS:如果这是一个愚蠢的问题,我很抱歉,但是我能找到的关于这个主题的几乎所有东西似乎都使用了
matplotlib.pyplot
变体。因此,我很难为
matplotlib.figure.figure
变体找到任何好的文档。

TL;博士 因此,问题是,为什么我们现在需要使用子图(使用matplotlib.figure.figure),而以前不需要(使用matplotlib.pyplot)

子地块
创建一个
对象。您以前确实有一个,但是
pyplot
API将它“隐藏”在封面下,因此您没有意识到它。您现在正试图直接使用对象,因此必须自己处理它

更详细的原因 您看到这种行为的原因在于
matplotlib.pyplot
的工作方式。引用一点:

matplotlib.pyplot
是命令风格函数的集合,使matplotlib像MATLAB一样工作
matplotlib.pyplot
是有状态的,因为它跟踪当前图形和打印区域,并且打印功能指向当前轴

关键是
pyplot
是有状态的。它在某种程度上跟踪“隐藏”状态并对您隐藏对象模型。它还做一些隐含的事情。因此,如果您只需调用,例如,
plt.axis()
,则在封面下调用,而反过来调用则会调用,因为您尚未通过
pyplot
设置图形。对于大多数调用
plt.some_function()
,这是正确的-如果
pyplot
没有处于自身状态的图形对象,它将创建一个

因此,在中间示例中,您创建了自己的
Figure
对象-为它命名
self.fig
(我不确定您的类结构是什么,所以我不知道
self
是什么,但我猜它是您的
tk.Frame
对象或类似的东西)

笑点
pyplot
对自己一无所知。fig。因此,在中间代码中,您在
pyplot
状态下对
Figure
对象调用
imshow()
,但在画布上显示不同的图形(
self.fig

问题不是您需要使用
子地块
,而是您需要更改正确的
图形
对象上的背景图像。您在潜在修复代码中使用
子批的方式可以做到这一点——尽管我建议下面的替代方法可能会使意图更清楚

如何修复 改变

plt.axis('off')
plt.tight_layout()
plt.imshow(image)

关于根本原因的说明:
pyplot
API与直接使用对象 这是一种观点,但可能会有所帮助。当我需要快速地将事物原型化并希望使用一个相当标准的案例时,我倾向于使用
pyplot
接口。通常,这就足够了

只要我需要做更复杂的事情,我就开始直接使用对象模型——维护我自己命名的
对象等


将两者混用是可能的,但往往令人困惑。您已经在中间解决方案中找到了这一点。所以我建议你做一个或另一个。

答案很好。使用子地块变量(正如我偶然发现的)或
fig.gca()
(如您在修复中列出的)哪个更好?在这种情况下,我认为
gca()
更容易阅读-我总是认为子地块让我觉得可能不止一个。然而,这实际上取决于个人偏好——两者都可以。如果在
gca()
之后执行
print(type(ax))
,您将看到其具体类型实际上是
AxesSubplot
(轴的子类)
)-与
add\u subplot()返回的完全相同
plt.axis('off')
plt.tight_layout()
plt.imshow(image)
self.fig.set_tight_layout(True)
ax = self.fig.gca() # You could use subplot here to get an Axes object instead
ax.axis('off')
ax.imshow(image)