When generating a figure to save to a pdf file, I'd like to adjust the positioning of the figure relative to the edges of the page, for example to add an inch margin along all sides. As far as I can tell, the solutions to do this (for example, in this question) either:
constrained_layout
mode -- applying plt.subplots_adjust()
after creating the figure but prior to fig.savefig()
messes up the constrained layoutbbox_inches="tight"
or pad=-1
don't seem to do anything meaningfulIs there a straightforward way to adjust external margins of a constrained layout figure?
For example:
fig = plt.figure(constrained_layout=True, figsize=(11, 8.5))
page_grid = gridspec.GridSpec(nrows=2, ncols=1, figure=fig)
# this doesn't appear to do anything with constrained_layout=True
page_grid.update(left=0.2, right=0.8, bottom=0.2, top=0.8)
top_row_grid = gridspec.GridSpecFromSubplotSpec(1, 3, subplot_spec=page_grid[0])
for i in range(3):
ax = fig.add_subplot(top_row_grid[:, i], aspect="equal")
n_bottom_row_plots = 10
qc_grid = gridspec.GridSpecFromSubplotSpec(1, n_bottom_row_plots, subplot_spec=page_grid[1])
for i, metric in enumerate(range(n_bottom_row_plots)):
ax = fig.add_subplot(qc_grid[:, i])
plt.plot(np.arange(5), np.arange(5))
fig.suptitle("my big label", fontweight="bold", fontsize="x-large", y=0.9)
# this ruins the constrained layout
# plt.subplots_adjust(left=0.2,right=0.8, bottom=0.2, top=0.8)
fig.savefig("temp.png", facecolor="coral")
Yields the following (I'd like to see more coral around the edges!):
Constrained layout attempts to resize subplots in a figure so that there are no overlaps between axes objects and labels on the axes.
The python plotting library matplotlib will by default add margins to any plot that it generates. They can be reduced to a certain degree through some options of savefig() , namely bbox_inches='tight' and pad_inches=0 .
To change the size of subplots in Matplotlib, use the plt. subplots() method with the figsize parameter (e.g., figsize=(8,6) ) to specify one size for all subplots — unit in inches — and the gridspec_kw parameter (e.g., gridspec_kw={'width_ratios': [2, 1]} ) to specify individual sizes.
Layout margins provide a visual buffer between a view’s content and any content outside of the view’s bounds. The layout margins consist of inset values for each edge (top, bottom, leading, and trailing) of the view. These inset values create a space between the edges of the view’s bounds rectangle and the content inside the view.
To set up constraints that respect the layout margins, enable the Constrain to margins option in Xcode, as shown in Figure 2. (If you do not enable that option, Xcode creates your constraints relative to the view’s bounds rectangle.)
Even if you are not using constraints to position your content, you can still manually position content relative to a view’s layout margins. The directionalLayoutMargins property of each view contains the edge inset values to use for the view’s margins.
“Gone Margin” is introduced with ConstraintLayout to solve this issue. Imagine that you have a hierarchy as shown above. You want to make A’s visibility GONE. When A is GONE, B will automatically slide to A’s position. In order to prevent that you can give gone_margin to the related direction.
Have you tried using the constrained layout padding option?
fig.set_constrained_layout_pads(w_pad=4./72., h_pad=4./72.,
hspace=0./72., wspace=0./72.)
While this might help with spacing, the constrained layout will restrict the amount of object that you can add to the defined space.
''' Here is the modified code '''
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import matplotlib.gridspec as gridspec
import numpy as np
fig = plt.figure(constrained_layout=True, figsize=(11, 8.5))
fig.set_constrained_layout_pads(w_pad=2./12., h_pad=4./12.,
hspace=0., wspace=0.)
page_grid = gridspec.GridSpec(nrows=2, ncols=1, figure=fig)
fig.suptitle("My BIG Label", fontweight="bold", fontsize="x-large", y=0.98)
# this doesn't appear to do anything with constrained_layout=True
page_grid.update(left=0.2, right=0.8, bottom=0.2, top=0.8)
top_row_grid = gridspec.GridSpecFromSubplotSpec(1, 3, subplot_spec=page_grid[0])
for i in range(3):
ax = fig.add_subplot(top_row_grid[:, i], aspect="equal")
n_bottom_row_plots = 10
qc_grid = gridspec.GridSpecFromSubplotSpec(1, n_bottom_row_plots, subplot_spec=page_grid[1])
for i, metric in enumerate(range(n_bottom_row_plots)):
ax = fig.add_subplot(qc_grid[:, i])
plt.plot(np.arange(5), np.arange(5))
# this ruins the constrained layout
# plt.subplots_adjust(left=0.2,right=0.8, bottom=0.2, top=0.8)
fig.savefig("temp.png", facecolor="coral")
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