Debian Linux 8.3 amd64, XMonad WM, python2.7, matplotlib 1.5.1
I'm making a plot, for example:
import matplotlib.pyplot as plt
x = xrange(10)
y1 = [i ** 2 for i in x]
y2 = [1.0 / (i + 1) for i in x]
fig = plt.figure()
ax1 = plt.subplot(1, 2, 1)
ax1.plot(x, y1)
ax2 = plt.subplot(1, 2, 2)
ax2.plot(x, y2)
plt.show()
and since I'm using tiling window manager, the matplotlib's window gets stretched to a tile. Unfortunately this makes the graphs small and layout somewhat loose.
If I want to "tighten" it a litte bit, clicking "Configure subplots->Tight Layout" does the job. But this means I have to click on the icon and then on the button every time and since I use this plot to display testing data and run it very often, it's quite annoying. So I tried a few things to make this easier:
calling plt.tight_layout()
before show()
:
...
ax2.plot(x, y2)
plt.tight_layout()
plt.show()
adding keypress handler (so I would just press "t"):
...
ax2.plot(x, y2)
def kbd_handler(event):
if event.key == 't':
plt.tight_layout()
plt.gcf().canvas.mpl_connect('key_press_event', kbd_handler)
plt.show()
calling tight_layout
on figure:
ax2.plot(x, y2)
fig.tight_layout()
plt.show()
It all changed nothing or at least it looked the same for 2 subplots in one row, however for more than one row, it made the layout even more loose and all subplots extremely small.
I believe the problem is related to resize which probably happens after the
window is created, so the tighten_layout
works with original window
dimensions. When the Window Manager resizes the window, the layout keeps the
subplot sizes and I have a "loose" layout with miniature graphs..
Is there a way to automaticaly (or very easily - like using a key_press_event)
tighten the layout even when the window gets resized immediately after
calling plt.show()
?
If you are using Matplotlib from within a script, the function plt. show() is your friend. plt. show() starts an event loop, looks for all currently active figure objects, and opens one or more interactive windows that display your figure or figures.
tight_layout automatically adjusts subplot params so that the subplot(s) fits in to the figure area. This is an experimental feature and may not work for some cases. It only checks the extents of ticklabels, axis labels, and titles.
All tight_layout does is calculate parameters for subplots_adjust , so tight_layout only works with subplots. Use fig, ax = plt. subplots() or ax = fig. add_subplot(1,1,1) instead of specifying the extent of the axes manually and it should work fine.
You can achieve what you want with the help of Matplotlib event handling. Just write a small function that calls tight_layout
and updates the figure every time the figure is resized:
from matplotlib import pyplot as plt
import numpy as np
x = np.linspace(0,np.pi,100)
y1 = np.sin(x)
y2 = np.cos(x)
fig, (ax1,ax2) = plt.subplots(nrows=1, ncols=2)
fig.tight_layout()
ax1.plot(x,y1)
ax2.plot(x,y2)
def on_resize(event):
fig.tight_layout()
fig.canvas.draw()
cid = fig.canvas.mpl_connect('resize_event', on_resize)
plt.show()
There is of course a small chance that this is system or version dependent. I verified the above example on MacOS Sierra with Python 3.5.4 (Matplotlib 2.0.2) and with Python 2.7.14 (Matplotlib 2.1.0). Hope this helps.
EDIT:
In fact, I think your keypress handler would have worked if you would have updated the figure after tight_layout
, i.e. if you would have called fig.canvas.draw()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With