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

时间:2011-09-16 19:41:12

标签: python matplotlib

我正在编写一个简单的Python应用程序,它使用matplotlib在屏幕上显示一些数字。生成的数字数量基于用户输入和整个应用程序生命周期的变化。用户能够发出“绘图”命令以生成具有所选数据系列的新图形窗口。为了改善用户体验,我想提供另一个命令,可以通过一些方便的方式以编程方式排列所有打开的图形窗口(例如,将它们平铺在可用的屏幕空间中)。

我相信已经找到了允许我调整图形窗口大小的API(以像素为单位),但是没有成功找到在屏幕上设置其绝对位置的方法。有没有办法在不深入了解正在使用的后端的细节的情况下做到这一点?我想以后端不可知的方式这样做,这样我就可以避免依赖可能在将来发生变化的实现细节。

11 个答案:

答案 0 :(得分:29)

最终找到了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)

我经常搜索这个,最后投入了30分钟来找到它。希望有所帮助。

答案 1 :(得分:12)

在目前为止的答案的帮助和我自己的一些修修补补,这是一个检查当前后端并使用正确语法的解决方案。

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()

答案 2 :(得分:11)

我不知道这是一种与后端无关的方法,但绝对可以为一些常见的后端做这件事,例如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")

所以我认为你可以用尽所有能够做到这一点的后端,如果不能选择某个后端。

答案 3 :(得分:5)

受@theo回答的启发,我编写了一个脚本来移动窗口并将其调整到屏幕上的特定标准位置。这是用Qt4Agg后端测试的:

import matplotlib.pyplot as plt

def move_figure(position="top-right"):
    '''
    Move and resize a window to a set of standard positions on the screen.
    Possible positions are:
    top, bottom, left, right, top-left, top-right, bottom-left, bottom-right
    '''

    mgr = plt.get_current_fig_manager()
    mgr.full_screen_toggle()  # primitive but works to get screen size
    py = mgr.canvas.height()
    px = mgr.canvas.width()

    d = 10  # width of the window border in pixels
    if position == "top":
        # x-top-left-corner, y-top-left-corner, x-width, y-width (in pixels)
        mgr.window.setGeometry(d, 4*d, px - 2*d, py/2 - 4*d)
    elif position == "bottom":
        mgr.window.setGeometry(d, py/2 + 5*d, px - 2*d, py/2 - 4*d)
    elif position == "left":
        mgr.window.setGeometry(d, 4*d, px/2 - 2*d, py - 4*d)
    elif position == "right":
        mgr.window.setGeometry(px/2 + d, 4*d, px/2 - 2*d, py - 4*d)
    elif position == "top-left":
        mgr.window.setGeometry(d, 4*d, px/2 - 2*d, py/2 - 4*d)
    elif position == "top-right":
        mgr.window.setGeometry(px/2 + d, 4*d, px/2 - 2*d, py/2 - 4*d)
    elif position == "bottom-left":
        mgr.window.setGeometry(d, py/2 + 5*d, px/2 - 2*d, py/2 - 4*d)
    elif position == "bottom-right":
        mgr.window.setGeometry(px/2 + d, py/2 + 5*d, px/2 - 2*d, py/2 - 4*d)


if __name__ == '__main__':

    # Usage example for move_figure()

    plt.figure(1)
    plt.plot([0, 1])
    move_figure("top-right")

    plt.figure(2)
    plt.plot([0, 3])
    move_figure("bottom-right")

答案 4 :(得分:4)

对于Qt4Agg,这对我有用。

fig = figure()
fig.canvas.manager.window.move(0,0)

在Win7上测试,mpl版本1.4.2,python 2.7.5

答案 5 :(得分:2)

这也有效:

fig = figure()
fig.canvas.manager.window.Move(100,400)

如果您想将图表发送到图片并使用默认图片管理器(可能会记住位置)打开图片,请使用here中的图片:

fig.savefig('abc.png')
from PIL import Image
im = Image.open("abc.jpg")
im.rotate(0).show()

答案 6 :(得分:2)

def show_img(img, title=""):
    plt.imshow(img)
    plt.title(title)
    thismanager = plt.get_current_fig_manager()
    thismanager.window.wm_geometry("+100+100")
    plt.show()

答案 7 :(得分:1)

对于Windows平台,您可以安装并使用Pyfig中的pyfig模块。

如下操作图形窗口的示例如下:

import pylab as p
import pyfig as fig
for ix in range(6): f = p.figure(ix)
fig.stack('all')
fig.stack(1,2)
fig.hide(1)
fig.restore(1)
fig.tile()
fig.pile()
fig.maximize(4)
fig.close('all')

答案 8 :(得分:1)

'''This is a way to resize the window to a given fraction of the screen.
It uses the screenSize in pixels. User specifies the fx and fy fraction
of the sreen or just a fraction. Couldn't fine how to really position the
window though. No hints in the current figmanager could be found.
But of course, this could be combined with mgr.canvas.move()

'''

import matplotlib.pyplot as plt
#pylab

def screenPos(f):
   '''reset window on screen to size given by fraction f
   where f may by a scalar or a tuple, and where all values
   are 0<=f<=1
   '''
   if type(f)==float: f=(f,) # assert we have a tuple
   mgr = plt.get_current_fig_manager()
   mgr.full_screen_toggle() # primitive but works
   py = mgr.canvas.height()
   px = mgr.canvas.width()
   mgr.resize(f[0]*px,f[-1]*py)
   return f[0]*px,f[-1]*py

px,py = screenPos(0.8)

答案 9 :(得分:1)

以下对我有用。

import matplotlib  
matplotlib.use("TkAgg") # set the backend  

if backend == 'TkAgg':  
    f.canvas.manager.window.wm_geometry("+%d+%d" % (x, y))

答案 10 :(得分:0)

如何定义一个函数来将窗口提升到顶层并将其移向左上角(例如),如下所示:

def topfig():
    figmgr = get_current_fig_manager()
    figmgr.canvas.manager.window.raise_()
    geom = figmgr.window.geometry()
    x,y,dx,dy = geom.getRect()
    figmgr.window.setGeometry(10, 10, dx, dy)

然后每当你打开一个新的数字时,你只需输入“topfig()”。有没有办法预先定义topfig,以便它始终可用?