<p>这里的主要问题是matplotlib图的大小是用<code>self._cwidg</code>调整的。由于假定地物始终与<code>self._cwidg</code>具有相同的大小,matplotlib仅重新绘制在<code>self._cwidg</code>中可见的地物部分,并且在地物大小更改时,后者不会调整大小</p>
<p>解决方法是使用额外的画布<code>self._scroll_canvas</code>,并将<code>self._cwidg</code>嵌入其中作为窗口。然后我用以下方式修改了<code>_change_size()</code>:</p>
<pre><code>def _change_size(self):
newsize = askfloat('Size', 'Input new size in inches')
if newsize is None:
return
w = newsize
h = newsize/1.8
self._cwidg.configure(width=int(w*self._conv_ratio), height=int(h*self._conv_ratio))
self._scroll_canvas.configure(scrollregion=self._scroll_canvas.bbox("all"))
</code></pre>
<p>我直接调整<code>self._cwidg</code>的大小,然后调整图形的大小,确保它的每个部分都被重新绘制。然后我更新滚动区域。以下是完整的代码:</p>
<pre><code>import tkinter as tk
from tkinter import ttk
from tkinter.simpledialog import askfloat
from matplotlib.figure import Figure
from matplotlib.axes import Axes
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
class InteractivePlot(tk.Frame):
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)
self._scroll_canvas = tk.Canvas(self)
self._figure = Figure(dpi=150)
self._canvas = FigureCanvasTkAgg(self._figure, master=self._scroll_canvas)
self._sizebutton = tk.Button(self, text="Size (in.)", command=self._change_size)
self._axis = self._figure.add_subplot(111)
# Plot some data just to have something to look at.
self._axis.plot([0, 1, 2, 3, 4, 5], [1, 1, 3, 3, 5, 5], label='Dummy Data')
self._cwidg = self._canvas.get_tk_widget()
self._scroll_canvas.create_window(0, 0, anchor='nw', window=self._cwidg)
self._scrx = ttk.Scrollbar(self, orient="horizontal", command=self._scroll_canvas.xview)
self._scry = ttk.Scrollbar(self, orient="vertical", command=self._scroll_canvas.yview)
self._scroll_canvas.configure(yscrollcommand=self._scry.set, xscrollcommand=self._scrx.set)
self._sizebutton.grid(row=0, column=0, sticky='w')
self._scroll_canvas.grid(row=1, column=0, sticky='news')
self._scrx.grid(row=2, column=0, sticky='ew')
self._scry.grid(row=1, column=1, sticky='ns')
self.rowconfigure(1, weight=1)
self.columnconfigure(0, weight=1)
self._canvas.draw()
wi = self._figure.get_figwidth()
wp = self._cwidg.winfo_reqwidth(),
self._conv_ratio = wp / wi # get inch to pixel conversion factor
self._scroll_canvas.configure(width=wp, height=self._cwidg.winfo_reqheight())
self._scroll_canvas.configure(scrollregion=self._scroll_canvas.bbox("all"))
def _change_size(self):
newsize = askfloat('Size', 'Input new size in inches')
if newsize is None:
return
w = newsize
h = newsize/1.8
self._cwidg.configure(width=int(w*self._conv_ratio), height=int(h*self._conv_ratio))
self._scroll_canvas.configure(scrollregion=self._scroll_canvas.bbox("all"))
root = tk.Tk()
plt = InteractivePlot(root, width=400, height=400)
plt.pack(fill=tk.BOTH, expand=True)
root.mainloop()
</code></pre>