你怎么用matplotlib设置graphics窗口的绝对位置?
我在写一个简单的Python应用程序,使用matplotlib在屏幕上显示一些数字。 生成的数字的数量是基于用户input和整个应用程序的生活中的变化。 用户有能力发出一个“绘图”命令来生成一个新的数字窗口与选定的数据系列。 为了改善用户体验,我想提供另一个命令,以编程方式将所有打开的数字窗口排列成一些方便的布局(例如,将它们跨越可用的屏幕空间)。
我相信已经find了API,允许我调整数字窗口的大小(以像素为单位),但是还没有find一种方法来设置屏幕上的绝对位置。 有没有办法做到这一点,而不研究任何后端正在使用的细节? 我想以后端无关的方式来做到这一点,所以我可以避免依赖将来可能会改变的实现细节。
不是我知道一个后端不可知的方式来做到这一点,但绝对有可能做一些常见的后端,如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")
所以我认为,如果强加一个特定的一个不是一个选项,那么你可以通过所有可以做到这一点的后端耗尽。
最终find了QT后端的解决scheme:
import matplotlib.pyplot as plt fig, ax = 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分钟才发现这一点。 希望能帮助别人。
受@theo答案的启发,我写了一个脚本来移动窗口并将其调整到屏幕上特定的标准位置。 这是与Qt4Agg后端testing:
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")
在迄今为止的答案和一些自己的修补的帮助下,这里是一个解决scheme,检查当前的后端,并使用正确的语法。
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) plt.show() f, ax = plt.subplots() move_figure(f, 500, 500)
对于Qt4Agg,这为我工作。
fig = figure() fig.canvas.manager.window.move(0,0)
在Win7上testing,mpl版本1.4.2,python 2.7.5
这也适用:
fig = figure() fig.canvas.manager.window.Move(100,400)
如果你想发送一个图像的图像,并打开它的默认图像pipe理器(这可能会记住位置)使用此从这里 :
fig.savefig('abc.png') from PIL import Image im = Image.open("abc.jpg") im.rotate(0).show()
对于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')
'''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)
如何定义一个函数来将窗口提升到顶层并将其移动到左上angular(例如),如下所示:
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)
然后,只要你打开一个新的数字,只需input“topfig()”。 有没有办法预先定义topfig,所以它总是可用?