Related
Just for curiosity I would like to know how to do this in the code below. I have been searching for an answer but is useless.
import numpy as np
import matplotlib.pyplot as plt
data=np.random.exponential(scale=180, size=10000)
print ('el valor medio de la distribucion exponencial es: ')
print np.average(data)
plt.hist(data,bins=len(data)**0.5,normed=True, cumulative=True, facecolor='red', label='datos tamano paqutes acumulativa', alpha=0.5)
plt.legend()
plt.xlabel('algo')
plt.ylabel('algo')
plt.grid()
plt.show()
I am on a Windows (WIN7), running Python 2.7.5 & Matplotlib 1.3.1.
I was able to maximize Figure windows for TkAgg, QT4Agg, and wxAgg using the following lines:
from matplotlib import pyplot as plt
### for 'TkAgg' backend
plt.figure(1)
plt.switch_backend('TkAgg') #TkAgg (instead Qt4Agg)
print '#1 Backend:',plt.get_backend()
plt.plot([1,2,6,4])
mng = plt.get_current_fig_manager()
### works on Ubuntu??? >> did NOT working on windows
# mng.resize(*mng.window.maxsize())
mng.window.state('zoomed') #works fine on Windows!
plt.show() #close the figure to run the next section
### for 'wxAgg' backend
plt.figure(2)
plt.switch_backend('wxAgg')
print '#2 Backend:',plt.get_backend()
plt.plot([1,2,6,4])
mng = plt.get_current_fig_manager()
mng.frame.Maximize(True)
plt.show() #close the figure to run the next section
### for 'Qt4Agg' backend
plt.figure(3)
plt.switch_backend('QT4Agg') #default on my system
print '#3 Backend:',plt.get_backend()
plt.plot([1,2,6,4])
figManager = plt.get_current_fig_manager()
figManager.window.showMaximized()
plt.show()
if you want to maximize multiple figures you can use
for fig in figs:
mng = fig.canvas.manager
# ...
Hope this summary of the previous answers (and some additions) combined in a working example (at least for windows) helps.
With Qt backend (FigureManagerQT) proper command is:
figManager = plt.get_current_fig_manager()
figManager.window.showMaximized()
This makes the window take up the full screen for me, under Ubuntu 12.04 with the TkAgg backend:
mng = plt.get_current_fig_manager()
mng.resize(*mng.window.maxsize())
This should work (at least with TkAgg):
wm = plt.get_current_fig_manager()
wm.window.state('zoomed')
(adopted from the above and Using Tkinter, is there a way to get the usable screen size without visibly zooming a window?)
For me nothing of the above worked. I use the Tk backend on Ubuntu 14.04 which contains matplotlib 1.3.1.
The following code creates a fullscreen plot window which is not the same as maximizing but it serves my purpose nicely:
from matplotlib import pyplot as plt
mng = plt.get_current_fig_manager()
mng.full_screen_toggle()
plt.show()
I usually use
mng = plt.get_current_fig_manager()
mng.frame.Maximize(True)
before the call to plt.show(), and I get a maximized window. This works for the 'wx' backend only.
EDIT:
for Qt4Agg backend, see kwerenda's answer.
My best effort so far, supporting different backends:
from platform import system
def plt_maximize():
# See discussion: https://stackoverflow.com/questions/12439588/how-to-maximize-a-plt-show-window-using-python
backend = plt.get_backend()
cfm = plt.get_current_fig_manager()
if backend == "wxAgg":
cfm.frame.Maximize(True)
elif backend == "TkAgg":
if system() == "Windows":
cfm.window.state("zoomed") # This is windows only
else:
cfm.resize(*cfm.window.maxsize())
elif backend == "QT4Agg":
cfm.window.showMaximized()
elif callable(getattr(cfm, "full_screen_toggle", None)):
if not getattr(cfm, "flag_is_max", None):
cfm.full_screen_toggle()
cfm.flag_is_max = True
else:
raise RuntimeError("plt_maximize() is not implemented for current backend:", backend)
I get mng.frame.Maximize(True) AttributeError: FigureManagerTkAgg instance has no attribute 'frame' as well.
Then I looked through the attributes mng has, and I found this:
mng.window.showMaximized()
That worked for me.
So for people who have the same trouble, you may try this.
By the way, my Matplotlib version is 1.3.1.
This is kind of hacky and probably not portable, only use it if you're looking for quick and dirty. If I just set the figure much bigger than the screen, it takes exactly the whole screen.
fig = figure(figsize=(80, 60))
In fact, in Ubuntu 16.04 with Qt4Agg, it maximizes the window (not full-screen) if it's bigger than the screen. (If you have two monitors, it just maximizes it on one of them).
I found this for full screen mode on Ubuntu
#Show full screen
mng = plt.get_current_fig_manager()
mng.full_screen_toggle()
import matplotlib.pyplot as plt
def maximize():
plot_backend = plt.get_backend()
mng = plt.get_current_fig_manager()
if plot_backend == 'TkAgg':
mng.resize(*mng.window.maxsize())
elif plot_backend == 'wxAgg':
mng.frame.Maximize(True)
elif plot_backend == 'Qt4Agg':
mng.window.showMaximized()
Then call function maximize() before plt.show()
The one solution that worked on Win 10 flawlessly.
import matplotlib.pyplot as plt
plt.plot(x_data, y_data)
mng = plt.get_current_fig_manager()
mng.window.state("zoomed")
plt.show()
For backend GTK3Agg, use maximize() – notably with a lower case m:
manager = plt.get_current_fig_manager()
manager.window.maximize()
Tested in Ubuntu 20.04 with Python 3.8.
Pressing the f key (or ctrl+f in 1.2rc1) when focussed on a plot will fullscreen a plot window. Not quite maximising, but perhaps better.
Other than that, to actually maximize, you will need to use GUI Toolkit specific commands (if they exist for your specific backend).
HTH
Here is a function based on #Pythonio's answer. I encapsulate it into a function that automatically detects which backend is it using and do the corresponding actions.
def plt_set_fullscreen():
backend = str(plt.get_backend())
mgr = plt.get_current_fig_manager()
if backend == 'TkAgg':
if os.name == 'nt':
mgr.window.state('zoomed')
else:
mgr.resize(*mgr.window.maxsize())
elif backend == 'wxAgg':
mgr.frame.Maximize(True)
elif backend == 'Qt4Agg':
mgr.window.showMaximized()
In my versions (Python 3.6, Eclipse, Windows 7), snippets given above didn't work, but with hints given by Eclipse/pydev (after typing: mng.), I found:
mng.full_screen_toggle()
It seems that using mng-commands is ok only for local development...
Try using 'Figure.set_size_inches' method, with the extra keyword argument forward=True. According to the documentation, this should resize the figure window.
Whether that actually happens will depend on the operating system you are using.
Try plt.figure(figsize=(6*3.13,4*3.13)) to make the plot larger.
Ok so this is what worked for me. I did the whole showMaximize() option and it does resize your window in proportion to the size of the figure, but it does not expand and 'fit' the canvas. I solved this by:
mng = plt.get_current_fig_manager()
mng.window.showMaximized()
plt.tight_layout()
plt.savefig('Images/SAVES_PIC_AS_PDF.pdf')
plt.show()
For Tk-based backend (TkAgg), these two options maximize & fullscreen the window:
plt.get_current_fig_manager().window.state('zoomed')
plt.get_current_fig_manager().window.attributes('-fullscreen', True)
When plotting into multiple windows, you need to write this for each window:
data = rasterio.open(filepath)
blue, green, red, nir = data.read()
plt.figure(1)
plt.subplot(121); plt.imshow(blue);
plt.subplot(122); plt.imshow(red);
plt.get_current_fig_manager().window.state('zoomed')
rgb = np.dstack((red, green, blue))
nrg = np.dstack((nir, red, green))
plt.figure(2)
plt.subplot(121); plt.imshow(rgb);
plt.subplot(122); plt.imshow(nrg);
plt.get_current_fig_manager().window.state('zoomed')
plt.show()
Here, both 'figures' are plotted in separate windows. Using a variable such as
figure_manager = plt.get_current_fig_manager()
might not maximize the second window, since the variable still refers to the first window.
I collected a few answers from the threads I was looking at when trying to achieve the same thing. This is the function I am using right now which maximizes all plots and doesn't really care about the backend being used. I run it at the end of the script. It does still run into the problem mentioned by others using multiscreen setups, in that fm.window.maxsize() will get the total screen size rather than just that of the current monitor. If you know the screensize you want them you can replace *fm.window.maxsize() with the tuple (width_inches, height_inches).
Functionally all this does is grab a list of figures, and resize them to matplotlibs current interpretation of the current maximum window size.
def maximizeAllFigures():
'''
Maximizes all matplotlib plots.
'''
for i in plt.get_fignums():
plt.figure(i)
fm = plt.get_current_fig_manager()
fm.resize(*fm.window.maxsize())
I have tried most of above solutions but none of them works well on my Windows 10 with Python 3.10.5.
Below is what I found that works perfectly on my side.
import ctypes
mng = plt.get_current_fig_manager()
mng.resize(ctypes.windll.user32.GetSystemMetrics(0), ctypes.windll.user32.GetSystemMetrics(1))
This doesn't necessarily maximize your window, but it does resize your window in proportion to the size of the figure:
from matplotlib import pyplot as plt
F = gcf()
Size = F.get_size_inches()
F.set_size_inches(Size[0]*2, Size[1]*2, forward=True)#Set forward to True to resize window along with plot in figure.
plt.show() #or plt.imshow(z_array) if using an animation, where z_array is a matrix or numpy array
This might also help: http://matplotlib.1069221.n5.nabble.com/Resizing-figure-windows-td11424.html
The following may work with all the backends, but I tested it only on QT:
import numpy as np
import matplotlib.pyplot as plt
import time
plt.switch_backend('QT4Agg') #default on my system
print('Backend: {}'.format(plt.get_backend()))
fig = plt.figure()
ax = fig.add_axes([0,0, 1,1])
ax.axis([0,10, 0,10])
ax.plot(5, 5, 'ro')
mng = plt._pylab_helpers.Gcf.figs.get(fig.number, None)
mng.window.showMaximized() #maximize the figure
time.sleep(3)
mng.window.showMinimized() #minimize the figure
time.sleep(3)
mng.window.showNormal() #normal figure
time.sleep(3)
mng.window.hide() #hide the figure
time.sleep(3)
fig.show() #show the previously hidden figure
ax.plot(6,6, 'bo') #just to check that everything is ok
plt.show()
I have a python project that outputs several Matplotlib figures; each figure contains several charts. The problem that project launches about 15 figures (windows) every run, which I can not reduce.
Is it possible to concatenate all these figures (windows) to a single tabbed window so that each tab represents one figure?
Any help is much appreciated.
Thanks in advance
Workaround
Thanks to #mobiusklein comments below he suggested a workaround, to export the figures as myltipage pdf file as shown here.
Important note about the multipage pdf example mentioned above.
I tried it, but I got an error regarding the LaTeX use in matplotlib. Because fixing this error is beyond the scope of this question, so I suggest if it occurs to anyone, to set plt.rc('text', usetex=False) instead of usetex=True
I still hope if someone have other solution or workaround to post it for the benefit of others.
I wrote a simple wrapper for matplotlib that does something like you're describing. You need pyqt5 for it to work though.
Here is the code, you build a plotWindow object and feed it figure handles. It'll create a new tab for each figure.
import matplotlib
# prevent NoneType error for versions of matplotlib 3.1.0rc1+ by calling matplotlib.use()
# For more on why it's nececessary, see
# https://stackoverflow.com/questions/59656632/using-qt5agg-backend-with-matplotlib-3-1-2-get-backend-changes-behavior
matplotlib.use('qt5agg')
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QTabWidget, QVBoxLayout
import matplotlib.pyplot as plt
import sys
class plotWindow():
def __init__(self, parent=None):
self.app = QApplication(sys.argv)
self.MainWindow = QMainWindow()
self.MainWindow.__init__()
self.MainWindow.setWindowTitle("plot window")
self.canvases = []
self.figure_handles = []
self.toolbar_handles = []
self.tab_handles = []
self.current_window = -1
self.tabs = QTabWidget()
self.MainWindow.setCentralWidget(self.tabs)
self.MainWindow.resize(1280, 900)
self.MainWindow.show()
def addPlot(self, title, figure):
new_tab = QWidget()
layout = QVBoxLayout()
new_tab.setLayout(layout)
figure.subplots_adjust(left=0.05, right=0.99, bottom=0.05, top=0.91, wspace=0.2, hspace=0.2)
new_canvas = FigureCanvas(figure)
new_toolbar = NavigationToolbar(new_canvas, new_tab)
layout.addWidget(new_canvas)
layout.addWidget(new_toolbar)
self.tabs.addTab(new_tab, title)
self.toolbar_handles.append(new_toolbar)
self.canvases.append(new_canvas)
self.figure_handles.append(figure)
self.tab_handles.append(new_tab)
def show(self):
self.app.exec_()
if __name__ == '__main__':
import numpy as np
pw = plotWindow()
x = np.arange(0, 10, 0.001)
f = plt.figure()
ysin = np.sin(x)
plt.plot(x, ysin, '--')
pw.addPlot("sin", f)
f = plt.figure()
ycos = np.cos(x)
plt.plot(x, ycos, '--')
pw.addPlot("cos", f)
pw.show()
This is also posted at: https://github.com/superjax/plotWindow
Hopefully this could be a good starting point for your application.
The backend you choose to use for matplotlib controls how each figure is displayed. Some backends just render figures to file, while others like the tk, qt, or gtk backends render figures in graphical windows. Those backends determine what functionality those GUI windows have.
The existing backends don't support the type of tabbed navigation you're looking for. Someone else here implemented this using Qt4.
You might also try writing your own report files with PDF or HTML which would let you more easily write more complex image arrangements with simpler libraries.
Something that is functionally similar might be implemented using the widgets. For example, provide a row of buttons, one button for each "tab", and repaint the graphical portion of the window in response to each button.
The buttons example as a workaround is creative. As another stated you can use PyQt to create a tabbed window.
It is for this reason I use PyQtGraph. PyQtGraph only uses PyQt as a backend and therefor "natively" supports both tabbed windows and "docks". Docks allow for movable tabs and splits as well as breaking off a tab or split to a new floating window.
In general, PyQtGraph's docks provide a method for organizing your graphs/plots/images that I haven't been able to get with other libraries.
Bokeh offers tabbed windows through their Panels and Tabs widgets.
I know it is not always feasible to move away from matplotlib but I felt like there was a lack of representation of libraries which have considered and implemented tools specifically for your use case.
I shared my code that allows docking and tabbing with drag-n-drop (qt docking system). It acts as a matplotlib backend, so it's easy to integrate.
https://github.com/peper0/mpldock
I recently released a python package which contains a class called DockablePlotWindow which provides a solution similar to superjax's answer but which provides a little more flexibility to organize how the plots are initially displayed.
I'm interested to continue improving this package so feel free to open pull requests or issues on github. You can find information about it here: https://github.com/nanthony21/mpl_qt_viz
and here:
https://nanthony21.github.io/mpl_qt_viz/
For some reason this code creates a figure that is only the standard size: it doesn't change the height or width (I chose widths and heights that are ludicrous to clearly illustrate the problem):
import matplotlib.pyplot as plt
fig = plt.figure()
fig.set_figwidth(30)
fig.set_figheight(1)
print('Width: {}'.format(fig.get_figwidth()))
plt.show()
I'm running on OSX 10.10.4, Python 3.4.3, Matplotlib 1.4.3. (Installed via Macports.) Any ideas? What am I missing?
The optional parameter forward propagates changes to the canvas in a GUI window that already exists.
Documentation here:
optional kwarg forward=True will cause the canvas size to be automatically updated; e.g., you can resize the figure window from the shell
Using Figure(figsize=(w,h)) also works.
For Matplotlib 2.2.0 and newer
forward=True is the default for all three of set_figheight, set_figwidth, and set_size_inches (set_size_inches changes both height and width simultaneously).
For Matplotlib 1.5.0
forward=True must be specified explicitly as it is False by default. (In Matplotlib 2.0.0, the default is changed to True only for set_size_inches).
For Matplotlib 1.4.3 and older
forward is only supported by set_size_inches.
set_figheight and set_figwidth do not support this argument, so it is a bit difficult to only change a single dimension of a pre-created GUI.
I'm not certain why those documented functions don't work, but they have been fixed for the next matplotlib release (>v1.4.3). As a workaround until the next release, replacing set_figwidth and set_figheight solves this problem.
import matplotlib.pyplot as plt
fig = plt.figure()
# Instead of set_figwidth(30)
fig.set_size_inches(30, fig.get_figheight(), forward=True)
plt.show()
I'm using Windows XP v3/Python 2.7 with Canopy and Anaconda package managers/editors.
I am using Python/Matplotlib to produce some Bland-Altman plots (statistical scatter plots) for publication.
After processing the data, the plt.show() command opens a new "Figure" window containing the plot, which looks fine.
I want to be able to use the dynamic pan and zoom commands in this window to interactively optimise the appearance of my plot, then save it as it appears in the window as a high resolution press-quality png image (400-600 dpi, 7 x 5 inches).
The default setting for saving images from the "Figure" window appears to be set to screen resolution (800 x 600 pixels), and I cannot find any options in this window which allow me to change these settings.
I've read other posts on this forum which explain how to directly save a plot from Python in higher resolution by using the following commands to manipulate dpi and image size, e.g.:
plt.figure(figsize=(18, 12), dpi=400)
plt.savefig("myplot.png", dpi = 400)
However, this is not the solution that I'm looking for; as I want to be able to modify the plot using the dynamic pan and zoom features of the "Figure" window before saving in a higher resolution than the default screen resolution.
I'd be grateful for your help.
Many thanks in anticipation & Happy New Year.
Dave
(UK)
Try this:
Determine how to set width and height using a pixels-to-inches converter, like in the following matplotlib documentation. Then try:
import matplotlib.pyplot as plt
fig = plt.figure(frameon=False)
fig.set_size_inches(width,height)
I had this issue in spyder and found changing the value in Preferences > iPython Console > Inline Backend > Resolution changes the resolution when I save figures from the built in window viewing application.
One may register an event upon a key press that would save the figure with some previously given size and dpi. The following uses a class that stores some figsize and dpi and upon pressing t wll change the figure size and dpi of the figure. It will then save this figure and restore the old size and dpi such that the figure on screen remains unchanged.
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
fig,ax=plt.subplots()
ax.plot([1,3,1])
class AnySizeSaver():
def __init__(self, fig=None, figsize=None, dpi=None, filename=None):
if not fig: fig=plt.gcf()
self.fig = fig
if not figsize: figsize=self.fig.get_size_inches()
self.figsize=figsize
if not dpi: dpi=self.fig.dpi
self.dpi=dpi
if not filename: filename="myplot.png"
self.filename=filename
self.cid = self.fig.canvas.mpl_connect("key_press_event", self.key_press)
def key_press(self, event):
if event.key == "t":
self.save()
def save(self):
oldfigsize = self.fig.get_size_inches()
olddpi=self.fig.dpi
self.fig.set_size_inches(self.figsize)
self.fig.set_dpi(self.dpi)
self.fig.savefig(self.filename, dpi=self.dpi)
self.fig.set_size_inches(oldfigsize, forward=True)
self.fig.set_dpi(olddpi)
self.fig.canvas.draw_idle()
print(fig.get_size_inches())
ass = AnySizeSaver(fig=fig, figsize=(3,3), dpi=600)
plt.show()
I'm working with python and matplotlib on mac os x.
When I'm working on many different windows and I have to run a script which produces a plot, the plot window always open behind the active window and is very frustration having to switch between windows for looking at the image.
Is it any why to decide the location of the plot window, and/or pop up it as foreground window?
thanks
For me (OSX 10.10.2, Matplotlib 1.4.3), what works is changing the matplotlib backend to TkAgg. Before importing pyplot or anything, go:
import matplotlib
matplotlib.use('TkAgg')
Plot windows now pop-up, and can be Command-Tab'ed to.
I was bothered by exactly the same problem. I found finally a solution (in pylab mode, with qt4agg backend):
get_current_fig_manager().window.raise_()
or
fig = gcf()
fig.canvas.manager.window.raise_()
Regards,
Markus
I found this solution was so often needed (e.g. when using Spyder IDE), I wrapped it into a function.
def show_plot(figure_id=None):
if figure_id is None:
fig = plt.gcf()
else:
# do this even if figure_id == 0
fig = plt.figure(num=figure_id)
plt.show()
plt.pause(1e-9)
fig.canvas.manager.window.activateWindow()
fig.canvas.manager.window.raise_()
I found a good answer on this thread:
How to make a Tkinter window jump to the front?
Basically, the idea is to use window attributes - set the '-topmost' attribute to True (1) to make the window come to the foreground, and then set it to False (0) so that it later allows other windows to appear in front of it. Here's code that worked for me:
import matplotlib.pyplot as plt
wm = plt.get_current_fig_manager()
wm.window.attributes('-topmost', 1)
wm.window.attributes('-topmost', 0)
For MacOS Sierra and python 3.6, Matplotlib 2.0.0
import matplotlib.pyplot as plt
plt.get_current_fig_manager().show()
the above line does the job no need of anything else.
This worked for me!!
(Tested on Mac OS X 10.11, Spyder 2.3.5.2 - Python 3.4)
Go to Preferences > IPython console > Graphics and set a backend to Qt (after that you need to restart the kernel).
Make a file that contains:
def raise_window(figname=None):
if figname: plt.figure(figname)
cfm = plt.get_current_fig_manager()
cfm.window.activateWindow()
cfm.window.raise_()
and import it at startup (Preferences > IPython console > Startup > Run a file). Now, just call function raise_window() below your code.
Example:
import numpy as np
import matplotlib.pyplot as plt
X = np.linspace(-np.pi, np.pi, 256)
C, S = np.cos(X), np.sin(X)
plt.figure()
plt.plot(X, C)
plt.plot(X, S)
raise_window()
For me only the following works (with TkAgg backend):
plt.gcf().canvas.get_tk_widget().focus_force()
As of matplotlib 1.5.1 on MacOSX 10.11.6, if you start an iPython (5.0.0, Python: 3.5.2) shell and use %matplotlib you can bring a matplotlib plot to the front using:
>>> %matplotlib
Using matplotlib backend: MacOSX
>>> import matplotlib.pyplot as plt
>>> plt.plot([1,3,2,4])
>>> plt.show()
** Edit: Advice seems to be not to use %pylab as it pollutes the global name space **
.. shell and use %pylab you can bring a matplotlib plot to the front using:
>>> %pylab
Using matplotlib backend: MacOSX
Populating the interactive namespace from numpy and matplotlib
>>> plot([1,3,2,4])
>>> show()
You can set
backend : MacOSX
in your matplotlibrc file for a permanent solution.
It works for me on macos mojave, with matplotlib 2.1.2. However, other users have complained that it does not work for them, so it might be affected by other settings
The following worked on Jupyter notebook with Qt5 backend on Windows. I tested it with Python 3.7, matplotlib 3.2.1.
%matplotlib qt5
import matplotlib.pyplot as plt
import numpy as np
from PyQt5 import QtCore
plt.plot(np.linspace(0,1))
window = plt.get_current_fig_manager().window
window.setWindowFlags(window.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
plt.show()
window.setWindowFlags(window.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint)
plt.show()