Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add external margins with constrained layout?

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:

  1. don't work with constrained_layout mode -- applying plt.subplots_adjust() after creating the figure but prior to fig.savefig() messes up the constrained layout
  2. don't actually quantitatively adjust the positioning of the figure -- adding bbox_inches="tight" or pad=-1 don't seem to do anything meaningful

Is 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!):

enter image description here

like image 618
Noah Avatar asked Aug 20 '20 12:08

Noah


People also ask

What is constrained layout Matplotlib?

Constrained layout attempts to resize subplots in a figure so that there are no overlaps between axes objects and labels on the axes.

How do I remove the margins in Matplotlib?

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 .

How do I make all the subplots the same size in Matplotlib?

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.

What are layout margins and how do they work?

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.

How do I set up constraints that respect the layout margins?

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.)

How to position content relative to a view’s layout margins?

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.

What is “gone margin” in constraintlayout?

“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.


1 Answers

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")
like image 186
Ares Zephyr Avatar answered Nov 01 '22 03:11

Ares Zephyr