2011-09-16 13 views
20

मैं एक साधारण पायथन एप्लिकेशन लिख रहा हूं जो स्क्रीन पर कुछ आंकड़े प्रदर्शित करने के लिए matplotlib का उपयोग करता है। जेनरेट किए गए आंकड़ों की संख्या उपयोगकर्ता इनपुट और एप्लिकेशन के पूरे जीवन में परिवर्तन पर आधारित है। उपयोगकर्ता को चयनित डेटा श्रृंखला के साथ एक नई आकृति विंडो उत्पन्न करने के लिए "प्लॉट" कमांड जारी करने की क्षमता है। उपयोगकर्ता अनुभव को बेहतर बनाने के लिए, मैं एक और कमांड प्रदान करना चाहता हूं जो कुछ सुविधाजनक व्यवस्था में प्रोग्रामेटिक रूप से सभी खुली आकृति खिड़कियों की व्यवस्था करेगा (उदाहरण के लिए उपलब्ध स्क्रीन स्पेस में उन्हें टाइल करें)।आप matplotlib के साथ आकृति खिड़कियों की पूर्ण स्थिति कैसे सेट करते हैं?

मुझे लगता है कि मुझे एपीआई मिली हैं जो मुझे आकृति विंडो (पिक्सल में) के आकार को समायोजित करने की अनुमति देती हैं, लेकिन स्क्रीन पर अपनी पूर्ण स्थिति निर्धारित करने के लिए कोई रास्ता खोजने में कोई सफलता नहीं मिली है। क्या बैकएंड उपयोग में आने वाले विवरणों के बारे में जानकारी देने के बिना ऐसा करने का कोई तरीका है? मैं इसे बैकएंड-अज्ञेय तरीके से करना चाहता हूं ताकि मैं कार्यान्वयन के विवरणों पर भरोसा कर सकूं जो भविष्य में बदल सकते हैं।

उत्तर

12

है नहीं मैं ऐसा करने के लिए बैकएंड-अज्ञेयवाद तरह से पता है, लेकिन निश्चित रूप से इसे कुछ सामान्य बैकेंड, जैसे, 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") 

को बदल तो मुझे लगता है कि आप सभी बैकेंड कि, ऐसा करने में सक्षम हैं अगर एक निश्चित एक भव्य एक विकल्प नहीं है के माध्यम से निकास कर सकते हैं।

+0

धन्यवाद। मैं अपने सिस्टम पर टीकेएजी का उपयोग कर रहा हूं, लेकिन मुझे नहीं लगता कि मैं मान सकता हूं कि अंतिम उपयोगकर्ता होगा। मैं यह लागू करने में सक्षम हो सकता हूं कि उपयोगकर्ता को उनमें से कुछ सबसेट का उपयोग करना चाहिए, हालांकि। –

+0

@ जेसन आर यह वास्तव में इस बात पर निर्भर करता है कि यह निर्दिष्ट स्थिति आपके आवेदन में कितनी महत्वपूर्ण है। यदि यह केवल उपयोगकर्ता अनुभव में सुधार के लिए था, तो आप बस जिस भी सबसेट की देखभाल कर सकते हैं, उसके लिए आप जा सकते हैं, अन्यथा, क्या आप केवल एक खिड़की उत्पन्न कर सकते हैं, और पुरानी उप_प्लॉट को मिटाने के दौरान गतिशील रूप से प्रत्येक प्लॉट को sub_plots के रूप में रख सकते हैं? – nye17

+3

डुनो क्यों, लेकिन मेरे लिए (विंडोज़, पायथन आइडल, पायथन 2.7, नोटपैड ++ से शुरू हुआ) 'thismanager.window.wm_geometry ("+ 500 + 0")' काम किया, 'thismanager.window.SetPosition ((500, 0)) 'didnt ;-) – tim

1

विंडोज प्लेटफ़ॉर्म के लिए आप 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') 
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() 
+1

' move ' – Olexandr

+2

में छोटे 'm' के साथ QT के साथ काम नहीं करता है। –

+0

दो पिछली टिप्पणियों को गठबंधन करने के लिए: कम से कम क्यूटी बैकएंड (Qt4Agg, और शायद Qt5Agg) का उपयोग करते समय, आकार बदलने के लिए सही आदेश 'fig.canvas.manager.window.move (100,400) 'है। GTK3Agg के लिए भी सच होना प्रतीत होता है, इसलिए मैं इस उत्तर को संपादित करूंगा। –

19
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- चौड़ाई एक पहले उन्हें बाहर पढ़ सकते हैं तो की तरह, पता नहीं होता है:: 0 अंत में क्यूटी बैकएंड के लिए समाधान पाया

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

और फिर सेट एक ही आकार के साथ नई स्थिति:

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

मैं इसके लिए अक्सर खोज रहा था और अंततः इसे खोजने के लिए 30 मिनट का निवेश किया। उम्मीद है कि किसी की मदद करता है।

+0

ग्रेट समाधान, साझा करने के लिए धन्यवाद! – Gabriel

+0

स्वीकार किए गए एक से बेहतर जवाब। – Muppet

+2

ध्यान दें कि mngr = get_current_fig_manager() के बजाय, हम fig.canvas.manager – poppie

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) 
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") 
+0

का भी उपयोग कर सकते हैं मैं मध्य विकल्प जोड़ने के बारे में कैसे जाऊं? – Rich

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()" टाइप करें। क्या टॉपफिग को पूर्व-परिभाषित करने का कोई तरीका है ताकि यह हमेशा उपलब्ध रहे?

3

Qt4Agg के लिए, यह मेरे लिए काम किया।

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

Win7, एमपीएल संस्करण 1.4.2, अजगर 2.7.5

7

जवाब अब तक की मदद से और कुछ अपने दम पर संवारता पर परीक्षण किया गया है, यहाँ एक समाधान है कि मौजूदा बैकएंड और उपयोगों के लिए जाँच करता है है सही वाक्यविन्यास।

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) 
+0

अरे, मैंने अभी कोशिश की है और एक त्रुटि मिली है: 'विशेषता त्रुटि:' एक्सिससबप्लॉट 'ऑब्जेक्ट में कोई विशेषता नहीं है' कैनवास ' – Rich

+0

यह एकमात्र उत्तर है जो मेरे लिए काम करेगा, खासकर' f.canvas.manager.window 'का उपयोग कर। ले जाने के() '। वाक्यविन्यास भी सबसे सरल है। – Anonymous

संबंधित मुद्दे