Python 3.x Matplotlib设置带有“imshow”的“axes”对象会导致y轴变为变量
说明 我已经开始根据matplotlib的未来警告重构一些代码,以重用最初定义的Python 3.x Matplotlib设置带有“imshow”的“axes”对象会导致y轴变为变量,python-3.x,matplotlib,tkinter,tkinter-canvas,Python 3.x,Matplotlib,Tkinter,Tkinter Canvas,说明 我已经开始根据matplotlib的未来警告重构一些代码,以重用最初定义的轴对象。然而,我注意到每当我重新使用我的轴对象时,图像大小都是可变的。因为,在使用imshow之后,我成功地将问题隔离到axes.imshow方法,该轴上任何后续图形的y轴都有一个y轴,似乎可以重新缩放 我的感觉是y轴比例保留在使用imshow绘制的初始图像中(我认为axes.clear应该重置此设置)。具体来说,在下面的示例中,混洗绘制了一些跨越9.90到10.10的数据,但由于原始图像跨越了0到50的范围,y轴几
轴
对象。然而,我注意到每当我重新使用我的轴
对象时,图像大小都是可变的。因为,在使用imshow
之后,我成功地将问题隔离到axes.imshow
方法,该轴上任何后续图形的y轴都有一个y轴,似乎可以重新缩放
我的感觉是y轴比例保留在使用imshow
绘制的初始图像中(我认为axes.clear
应该重置此设置)。具体来说,在下面的示例中,混洗绘制了一些跨越9.90到10.10的数据,但由于原始图像跨越了0到50的范围,y轴几乎不可见
下面是预期行为和“被窃听”行为的前两个屏幕截图,然后是一个MVCE,它有两个部分可以切换以获得预期行为或“被窃听”行为:
图像
imshow的飞溅
:
imshow
飞溅:
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg
)
import tkinter as tk
from matplotlib import image, figure
from numpy import random, linspace
from os import path, getcwd
from pylab import get_cmap
class Foo(object):
@classmethod
def run(cls):
root = tk.Tk()
Foo(root)
root.mainloop()
def __init__(self, master):
# Figure & canvas
self.fig = figure.Figure(figsize=(5,5))
self.axes = self.fig.add_subplot(111)
self.canvas = FigureCanvasTkAgg(self.fig, master=master)
self.canvas.get_tk_widget().pack(fill=tk.BOTH, expand=tk.YES)
# Splash image (This 'bugs')
Z = random.random((50,50))
self.axes.imshow(Z, cmap=get_cmap("Spectral"), interpolation='nearest')
self.canvas.draw()
# Dummy start data (This Works)
#self.axes.plot(random.normal(10,0.05,100))
#self.canvas.draw()
# MENU
menu = tk.Menu(master)
master.config(menu=menu)
test_menu = tk.Menu(menu, tearoff=0)
menu.add_cascade(label="Foo", menu=test_menu)
test_menu.add_command(label="Shuffle",
command=self.shuffle)
test_menu.add_command(label="Add",
command=self.add)
def add(self):
x_data = linspace(0,10, 1000)
y_data = random.normal(x_data)
self.axes.plot(x_data, y_data)
self.canvas.draw()
def shuffle(self):
self.axes.clear()
self.axes.plot(random.normal(10,0.05,100))
self.canvas.draw()
if __name__ == "__main__":
Foo.run()
问题
这里发生了什么,特别是什么导致图像看起来如此不同,以及可以对其采取什么措施?当没有为
方面
提供参数时,它默认为无。从:
如果没有,则默认为rc image.aspect值
因此,如果imshow没有参数,它将使用“image.aspect”的rcParam,您可以通过以下操作找到:
print (plt.rcParams["image.aspect"]) # default is "equal"
解决问题的方法是使用轴在shuffle
函数中将其设置为“auto”。set_aspect()
:
如果您不介意更改imshow的纵横比,还有一个aspect=
参数:
self.axes.imshow(Z, cmap=get_cmap("Spectral"), interpolation='nearest', aspect="auto")
我没有意识到,imshow
改变了外观,这确实造成了问题。但是,我选择在初始的imshow
行中设置它,如下所示:self.axes.imshow(Z,aspect='auto')
@BasJansen是,这也是一个选项。我更新了答案,在大多数情况下,matplotlib中的None
表示“默认值”。对于imshow
,默认方面是“相等”
。纵横比通过轴传播。一旦设置了轴方面,它将保持该设置,直到您再次更改它。这就是这个答案通过self.axes.set_aspect(“auto”)
@ImportanceOfBeingErnest所做的,所以如果imshow
默认为“equal”,这是否意味着它会覆盖rcParams[“image.aspect”]
?不,抱歉。它默认为rcParams[“image.aspect”]
,默认情况下是“equal”
。
self.axes.imshow(Z, cmap=get_cmap("Spectral"), interpolation='nearest', aspect="auto")