gpt4 book ai didi

python - 为什么子图没有占用嵌入 Tkinter 的 Matplotlib 中图形允许的所有空间?

转载 作者:行者123 更新时间:2023-12-01 16:30:37 25 4
gpt4 key购买 nike

我想在 Tkinter 窗口中显示很多子图,并且能够向下滚动以查看所有大小合适的图。然而,它都被打包了,而且子图似乎没有占用我图中允许的所有空间,而仅限制在窗口的空间内。如何使其间隔更宽并使子图更大?

我尝试使用 tight_layout() 选项进行不同的填充,更改图形大小和 Tkinter 的其他参数,例如 fillexpand 在我的小部件中。

import tkinter as tk
from tkinter import Scrollbar
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

import matplotlib.pyplot as plt

class ScrollableWindow:

def __init__(self, master, fig, **options):

master.geometry("%dx%d+0+0" % (800, 500))
master.focus_set()

fig_wrapper = tk.Frame(master, width=800, height=fig.get_figheight())
fig_wrapper.pack(fill=tk.BOTH, expand=True)

fig_canvas = FigureCanvasTkAgg(fig, master=fig_wrapper)

scrollbar = Scrollbar(fig_wrapper, orient=tk.VERTICAL, command=fig_canvas.get_tk_widget().yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
fig_canvas.get_tk_widget().pack(fill=tk.BOTH, side=tk.LEFT, expand=True)
fig_canvas.get_tk_widget().config(yscrollcommand = scrollbar.set, scrollregion=fig_canvas.get_tk_widget().bbox("all"), width=800, height=1000)



n_col, n_row = 3, 11

fig, axes = plt.subplots(figsize=(n_col,n_row*2), ncols=n_col, nrows=n_row)
for i in range(axes.shape[0]):
for j in range(axes.shape[1]):
axes[i,j].set_xlabel("xlabel")
axes[i,j].set_ylabel("ylabel")
fig.tight_layout()
showStatsWindow = tk.Tk()
showStatsWindow_ = ScrollableWindow(showStatsWindow, fig)
showStatsWindow.mainloop()

这是一个带有空图的示例。我想每行有 3 或 4 个子图,但它们都挤在一起。正如你所看到的,我的窗口中有更多的空间,它随着 Figsize 参数的变化而变化,但它都是空白的。

最佳答案

首先让我从显示 matplotlib 图形的 tkinter-Window大小开始,例如子图。实际上,固定的窗口大小 master.geometry("%dx%d+0+0"% (800, 500)) 困扰着你。

当您仅使用 tkinter 窗口时,它会自动将自身调整为图形大小。相反,如果调整大小,图形也会调整大小。对于上述问题有一个简单的解决方法。

  • Replace the following line :

    master.geometry("%dx%d+0+0" % (800, 500))
  • with:

    master.resizable(width=False, height=False)

防止 tkinter 窗口被调整大小。现在,要使子图的大小更大或更小,您可以通过相应地更改 figsize=() 参数来更改它。

fig, axes = plt.subplots(ncols=n_col, nrows=n_row, figsize=(7.5, 25))

我必须建议您使用 PyQT5,它在您给定的场景中更可行。下面给出了一个有效的示例,其中不调用 tkinter 自定义操作,例如 pack()config() 等等

Qt5 将图形放入带有滚动条的 Canvas 中,以便图形保留其原始大小并可以在 Qt 窗口内滚动。您不必处理类内部的详细信息,而只需处理脚本末尾的调用。

访问引用:Developing GUIs in Python: Tkinter vs PyQt .

import matplotlib
from PyQt5 import QtWidgets
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar

matplotlib.use('Qt5Agg')
matplotlib.use('TkAgg')


class ScrollableWindow(QtWidgets.QMainWindow):
def __init__(self, fig):

self.q_app = QtWidgets.QApplication([])

QtWidgets.QMainWindow.__init__(self)

# To set this size of the Display Window
self.setFixedSize(800, 500)

self.widget = QtWidgets.QWidget()
self.setCentralWidget(self.widget)
self.widget.setLayout(QtWidgets.QVBoxLayout())
self.widget.layout().setContentsMargins(0, 0, 0, 0)
self.widget.layout().setSpacing(10)

self.fig = fig
self.canvas = FigureCanvas(self.fig)
self.canvas.draw()
self.scroll = QtWidgets.QScrollArea(self.widget)
self.scroll.setWidget(self.canvas)

self.nav = NavigationToolbar(self.canvas, self.widget)
self.widget.layout().addWidget(self.nav)
self.widget.layout().addWidget(self.scroll)

self.show()
exit(self.q_app.exec_())


fig, axes = plt.subplots(ncols=3, nrows=11, figsize=(7.5, 25))

for i in range(axes.shape[0]):
for j in range(axes.shape[1]):
axes[i, j].set_xlabel("x-label")
axes[i, j].set_ylabel("y-label")


fig.tight_layout()
ScrollableWindow(fig)

这是使用 PyQT5 的结果:

Simple Result with PyQT5

关于python - 为什么子图没有占用嵌入 Tkinter 的 Matplotlib 中图形允许的所有空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57929563/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com