-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
[ENH]: add Figure.align_titles() functionality #22793
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1e38349
3183036
fff5a42
3ade95b
e0a20cc
8f71fd1
f5de111
8b27ae3
a3d8ccd
681abfe
f23d9e0
83e89a1
e3c50f8
3ac7d45
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
""" | ||
=============== | ||
Aligning Labels | ||
=============== | ||
|
||
Aligning titles using `.Figure.align_titles`. | ||
|
||
Note that the title "Title 1" would normally be much closer to the | ||
figure's axis. | ||
""" | ||
import matplotlib.pyplot as plt | ||
fig, axs = plt.subplots(2, 2, | ||
subplot_kw={"xlabel": "x", "ylabel": "", "title": "t"}) | ||
print(axs.shape) | ||
axs[0][0].imshow(plt.np.zeros((3, 5))) | ||
axs[0][1].imshow(plt.np.zeros((5, 3))) | ||
axs[1][0].imshow(plt.np.zeros((1, 2))) | ||
axs[1][1].imshow(plt.np.zeros((2, 1))) | ||
axs[0][0].set_title('t2') | ||
rowspan1 = axs[0][0].get_subplotspec().rowspan | ||
print(rowspan1, rowspan1.start, rowspan1.stop) | ||
rowspan2 = axs[1][1].get_subplotspec().rowspan | ||
print(rowspan2, rowspan2.start, rowspan2.stop) | ||
|
||
fig.align_titles() | ||
plt.show() |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -2950,7 +2950,7 @@ def _update_title_position(self, renderer): | |||||
_log.debug('title position was updated manually, not adjusting') | ||||||
return | ||||||
|
||||||
titles = (self.title, self._left_title, self._right_title) | ||||||
titles = [self.title, self._left_title, self._right_title] | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this required? It doesn't look like you are actually modifying There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
for title in titles: | ||||||
x, _ = title.get_position() | ||||||
|
@@ -3008,6 +3008,17 @@ def _update_title_position(self, renderer): | |||||
x, _ = title.get_position() | ||||||
title.set_position((x, ymax)) | ||||||
|
||||||
# Align bboxes of grouped axes to highest in group | ||||||
grouped_axs = self.figure._align_label_groups['title'] \ | ||||||
.get_siblings(self) | ||||||
bb_ymax = None | ||||||
ax_max = None | ||||||
for ax in grouped_axs: | ||||||
if bb_ymax is None or ax.bbox.ymax > bb_ymax: | ||||||
bb_ymax = ax.bbox.ymax | ||||||
ax_max = ax | ||||||
self.bbox = ax_max.bbox | ||||||
|
||||||
# Drawing | ||||||
@martist.allow_rasterization | ||||||
def draw(self, renderer): | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -173,7 +173,8 @@ def __init__(self, **kwargs): | |
# groupers to keep track of x and y labels we want to align. | ||
# see self.align_xlabels and self.align_ylabels and | ||
# axis._get_tick_boxes_siblings | ||
self._align_label_groups = {"x": cbook.Grouper(), "y": cbook.Grouper()} | ||
self._align_label_groups = {"x": cbook.Grouper(), "y": cbook.Grouper(), | ||
"title": cbook.Grouper()} | ||
|
||
self.figure = self | ||
# list of child gridspecs for this figure | ||
|
@@ -1241,6 +1242,60 @@ def align_xlabels(self, axs=None): | |
# grouper for groups of xlabels to align | ||
self._align_label_groups['x'].join(ax, axc) | ||
|
||
def align_titles(self, axs=None): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we want to add |
||
""" | ||
Align the titles of subplots in the same subplot column if title | ||
alignment is being done automatically (i.e. the title position is | ||
not manually set). | ||
|
||
Alignment persists for draw events after this is called. | ||
|
||
Parameters | ||
---------- | ||
axs : list of `~matplotlib.axes.Axes` | ||
Optional list of (or ndarray) `~matplotlib.axes.Axes` | ||
to align the titles. | ||
Default is to align all Axes on the figure. | ||
|
||
See Also | ||
-------- | ||
matplotlib.figure.Figure.align_xlabels | ||
matplotlib.figure.Figure.align_ylabels | ||
matplotlib.figure.Figure.align_labels | ||
|
||
Notes | ||
----- | ||
This assumes that ``axs`` are from the same `.GridSpec`, so that | ||
their `.SubplotSpec` positions correspond to figure positions. | ||
|
||
Examples | ||
-------- | ||
Example with titles:: | ||
|
||
fig, axs = subplots(1, 2, | ||
subplot_kw={"xlabel": "x", "ylabel": "y", "title": "t"}) | ||
axs[0].imshow(zeros((3, 5))) | ||
axs[1].imshow(zeros((5, 3))) | ||
fig.align_labels() | ||
fig.align_titles() | ||
""" | ||
if axs is None: | ||
axs = self.axes | ||
axs = np.ravel(axs) | ||
axs = [ax for ax in axs if hasattr(ax, 'get_subplotspec')] | ||
locs = ['left', 'center', 'right'] | ||
for ax in axs: | ||
for loc in locs: | ||
if ax.get_title(loc=loc): | ||
_log.debug(' Working on: %s', ax.get_title(loc=loc)) | ||
rowspan = ax.get_subplotspec().rowspan | ||
for axc in axs: | ||
for loc in locs: | ||
rowspanc = axc.get_subplotspec().rowspan | ||
if rowspan.start == rowspanc.start or \ | ||
rowspan.stop == rowspanc.stop: | ||
self._align_label_groups['title'].join(ax, axc) | ||
|
||
def align_ylabels(self, axs=None): | ||
""" | ||
Align the ylabels of subplots in the same subplot column if label | ||
|
@@ -2848,6 +2903,7 @@ def draw(self, renderer): | |
|
||
artists = self._get_draw_artists(renderer) | ||
try: | ||
|
||
renderer.open_group('figure', gid=self.get_gid()) | ||
if self.axes and self.get_layout_engine() is not None: | ||
try: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import matplotlib as plt | ||
fig, axs = plt.subplots(2, 2, | ||
subplot_kw={"xlabel": "x", "ylabel": "", "title": "t"}) | ||
print(axs.shape) | ||
axs[0][0].imshow(plt.zeros((3, 5))) | ||
axs[0][1].imshow(plt.zeros((5, 3))) | ||
axs[1][0].imshow(plt.zeros((1, 2))) | ||
axs[1][1].imshow(plt.zeros((2, 1))) | ||
axs[0][0].set_title('t2') | ||
rowspan1 = axs[0][0].get_subplotspec().rowspan | ||
print(rowspan1, rowspan1.start, rowspan1.stop) | ||
rowspan2 = axs[1][1].get_subplotspec().rowspan | ||
print(rowspan2, rowspan2.start, rowspan2.stop) | ||
|
||
fig.align_labels() | ||
fig.align_titles() | ||
plt.show() | ||
print("DONE") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?