如何设置matplotlib图形窗口的绝对位置?

62 投票
11 回答
110506 浏览
提问于 2025-04-17 02:27

我正在写一个简单的Python应用程序,使用matplotlib来在屏幕上显示一些图形。生成的图形数量是根据用户输入的内容来决定的,并且在应用程序运行过程中会有所变化。用户可以发出“绘图”命令,生成一个新的图形窗口,显示选定的数据系列。为了提升用户体验,我想提供另一个命令,能够自动将所有打开的图形窗口以某种方便的方式排列(比如在可用的屏幕空间上平铺)。

我相信我找到了可以调整图形窗口大小(以像素为单位)的接口,但还没有找到一种方法来设置它们在屏幕上的绝对位置。有没有办法做到这一点,而不需要深入了解所使用的后端的细节?我希望以一种与后端无关的方式来实现,这样就可以避免依赖可能在未来发生变化的实现细节。

11 个回答

42

在之前的回答和我自己的一些尝试帮助下,这里有一个解决方案,它会检查当前使用的后端,并使用正确的语法。

import matplotlib
import matplotlib.pyplot as plt

def move_figure(f, x, y):
    """Move figure's upper left corner to pixel (x, y)"""
    backend = matplotlib.get_backend()
    if backend == 'TkAgg':
        f.canvas.manager.window.wm_geometry("+%d+%d" % (x, y))
    elif backend == 'WXAgg':
        f.canvas.manager.window.SetPosition((x, y))
    else:
        # This works for QT and GTK
        # You can also use window.setGeometry
        f.canvas.manager.window.move(x, y)

f, ax = plt.subplots()
move_figure(f, 500, 500)
plt.show()
54

找到了QT后端的解决办法:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
mngr = plt.get_current_fig_manager()
# to put it into the upper left corner for example:
mngr.window.setGeometry(50,100,640, 545)

如果你不知道x和y的宽度,可以先把它们读出来,像这样:

# get the QTCore PyRect object
geom = mngr.window.geometry()
x,y,dx,dy = geom.getRect()

然后用相同的大小设置新的位置:

mngr.window.setGeometry(newX, newY, dx, dy)
17

我知道的没有一种和后端无关的方法来做到这一点,但对于一些常见的后端,比如 WX、tkagg 等,确实是可以实现的。

import matplotlib
matplotlib.use("wx")
from pylab import *
figure(1)
plot([1,2,3,4,5])
thismanager = get_current_fig_manager()
thismanager.window.SetPosition((500, 0))
show()

根据 @tim 在下面评论区的说法,你可能想要切换到

thismanager.window.wm_geometry("+500+0")

来试试。对于 TkAgg,只需要改成

thismanager.window.wm_geometry("+500+0")

所以我觉得你可以尝试所有能够做到这一点的后端,如果不想强制使用某一个的话。

撰写回答