Skip to content

Commit 0ba29f5

Browse files
authored
Merge pull request matplotlib#29945 from jklymak/doc-fixed-aspect-colorbar
Doc fixed aspect colorbar
2 parents 40c4178 + 4149f8d commit 0ba29f5

File tree

2 files changed

+66
-33
lines changed

2 files changed

+66
-33
lines changed

galleries/users_explain/axes/colorbar_placement.py

+37-33
Original file line numberDiff line numberDiff line change
@@ -143,43 +143,47 @@
143143
# Colorbars attached to fixed-aspect-ratio Axes
144144
# ---------------------------------------------
145145
#
146-
# Placing colorbars for Axes with a fixed aspect ratio pose a particular
147-
# challenge as the parent Axes changes size depending on the data view.
146+
# Axes with a fixed aspect ratio may shrink in height to preserve the aspect
147+
# ratio of the underlying data. This can result in the colorbar becoming taller
148+
# than the associated Axes, as demonstrated in the following example.
148149

149-
fig, axs = plt.subplots(2, 2, layout='constrained')
150-
cmaps = ['RdBu_r', 'viridis']
151-
for col in range(2):
152-
for row in range(2):
153-
ax = axs[row, col]
154-
pcm = ax.pcolormesh(np.random.random((20, 20)) * (col + 1),
155-
cmap=cmaps[col])
156-
if col == 0:
157-
ax.set_aspect(2)
158-
else:
159-
ax.set_aspect(1/2)
160-
if row == 1:
161-
fig.colorbar(pcm, ax=ax, shrink=0.6)
150+
fig, ax = plt.subplots(layout='constrained', figsize=(4, 4))
151+
pcm = ax.imshow(np.random.randn(10, 10), cmap='viridis')
152+
fig.colorbar(pcm, ax=ax)
162153

163154
# %%
164-
# We solve this problem using `.Axes.inset_axes` to locate the Axes in "axes
165-
# coordinates" (see :ref:`transforms_tutorial`). Note that if you zoom in on
166-
# the parent Axes, and thus change the shape of it, the colorbar will also
167-
# change position.
155+
# To automatically adjust the colorbar size to match the parent Axes, we can
156+
# use ``layout='compressed'``. This ensures that as the figure is resized or
157+
# the fixed-aspect-ratio Axes is zoomed in or out, the colorbar dynamically
158+
# resizes to align with the parent Axes.
168159

169-
fig, axs = plt.subplots(2, 2, layout='constrained')
170-
cmaps = ['RdBu_r', 'viridis']
171-
for col in range(2):
172-
for row in range(2):
173-
ax = axs[row, col]
174-
pcm = ax.pcolormesh(np.random.random((20, 20)) * (col + 1),
175-
cmap=cmaps[col])
176-
if col == 0:
177-
ax.set_aspect(2)
178-
else:
179-
ax.set_aspect(1/2)
180-
if row == 1:
181-
cax = ax.inset_axes([1.04, 0.2, 0.05, 0.6])
182-
fig.colorbar(pcm, cax=cax)
160+
fig, ax = plt.subplots(layout='compressed', figsize=(4, 4))
161+
pcm = ax.imshow(np.random.randn(10, 10), cmap='viridis')
162+
ax.set_title("Colorbar with layout='compressed'", fontsize='medium')
163+
fig.colorbar(pcm, ax=ax)
164+
165+
# %%
166+
# Alternatively, we can manually position the colorbar using `.Axes.inset_axes`
167+
# with axes-relative coordinates. This approach provides precise control over
168+
# the colorbar's placement. However, without a layout engine, the colorbar
169+
# might be clipped if it extends beyond the figure boundaries.
170+
171+
fig, ax = plt.subplots(layout='constrained', figsize=(4, 4))
172+
pcm = ax.imshow(np.random.randn(10, 10), cmap='viridis')
173+
cax = ax.inset_axes([1.04, 0.0, 0.05, 1.0]) # Positioning the colorbar
174+
ax.set_title('Colorbar with inset_axes', fontsize='medium')
175+
fig.colorbar(pcm, cax=cax)
176+
177+
# %%
178+
# We can also do this manually using an `.Axes.inset_axes` using axes-relative
179+
# coordinates (see :ref:`transforms_tutorial`). Note that if we do not use a
180+
# layout engine, the colorbar will be clipped off the right side of the figure.
181+
182+
fig, ax = plt.subplots(layout='constrained', figsize=(4, 4))
183+
pcm = ax.imshow(np.random.randn(10, 10), cmap='viridis')
184+
cax = ax.inset_axes([1.04, 0.0, 0.05, 1.0])
185+
ax.set_title('Colorbar with inset_axes', fontsize='medium')
186+
fig.colorbar(pcm, cax=cax)
183187

184188
# %%
185189
# .. seealso::

galleries/users_explain/axes/constrainedlayout_guide.py

+29
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,35 @@ def example_plot(ax, fontsize=12, hide_labels=False):
493493
ax.imshow(arr)
494494
fig.suptitle("fixed-aspect plots, layout='compressed'")
495495

496+
# %%
497+
# Compressed layout will also attempt to size colorbars to match the size of the
498+
# fixed-aspect-ratio parent Axes as the figure is resized or the aspect ratio changes.
499+
# In the following figure, the colorbar is taller than its parent Axes:
500+
501+
fig, ax = plt.subplots(layout='constrained', figsize=(3, 3))
502+
pcm = ax.imshow(np.random.randn(10, 10), cmap='viridis')
503+
ax.set_title("Colorbar with layout='constrained'", fontsize='medium')
504+
fig.colorbar(pcm, ax=ax)
505+
506+
# %%
507+
# Compressed layout ensures that the height of the colorbar matches the height
508+
# of its parent Axes, maintaining a consistent appearance:
509+
510+
fig, ax = plt.subplots(layout='compressed', figsize=(3, 3))
511+
pcm = ax.imshow(np.random.randn(10, 10), cmap='viridis')
512+
ax.set_title("Colorbar with layout='compressed'", fontsize='medium')
513+
fig.colorbar(pcm, ax=ax)
514+
515+
# %%
516+
# If the Axes is zoomed in or out, or the figure is resized, the colorbar will
517+
# dynamically resize to match the parent Axes. Whether this behavior is desired
518+
# depends on the specific application:
519+
520+
fig, ax = plt.subplots(layout='compressed', figsize=(3, 3))
521+
pcm = ax.imshow(np.random.randn(10, 10), cmap='viridis')
522+
ax.set_ylim([4, 8])
523+
ax.set_title("Layout='compressed' with zoom", fontsize='medium')
524+
fig.colorbar(pcm, ax=ax)
496525

497526
# %%
498527
# Manually turning off *constrained layout*

0 commit comments

Comments
 (0)