Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Align titles #22376#25591

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from10 commits
Commits
Show all changes
14 commits
Select commitHold shift + click to select a range
d1067a6
Used previous pull request and now trying to figure out why savefigur…
AlextheGreat1509Mar 28, 2023
e84960d
Fixed bbox issue not being updated when title position is changed.
SirSkillfulMar 30, 2023
d6d5d7f
Renamed align_titles to avoid confusion with the axis labels. Also re…
SirSkillfulMar 30, 2023
065d992
Added tests from original pull request to test our solution
AlextheGreat1509Mar 30, 2023
7f5220a
Changed test to try different way of accessing savefig function as cu…
AlextheGreat1509Mar 30, 2023
838ace3
Updated code comments
AlextheGreat1509Mar 31, 2023
9decc20
Refactoring of align_titles function
SirSkillfulMar 31, 2023
e8042f8
Merge branch 'matplotlib:main' into align_titles
AlextheGreat1509Mar 31, 2023
52164fa
Fixed flake8 issues
AlextheGreat1509Mar 31, 2023
b44fb00
Fixed flake8 issues
AlextheGreat1509Mar 31, 2023
3741239
Fixed flake8 formating issues
SirSkillfulMar 31, 2023
4eb53e6
Changed fix for savefig
SirSkillfulApr 3, 2023
938d9e5
Merge remote-tracking branch 'origin/align_titles' into align_titles
AlextheGreat1509Apr 6, 2023
1fe094a
Changed tests to use new styling standard. Titles now align as expect…
AlextheGreat1509Apr 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletionslib/matplotlib/axes/_base.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2990,6 +2990,16 @@ 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):
Expand Down
69 changes: 66 additions & 3 deletionslib/matplotlib/figure.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -183,10 +183,11 @@ def __init__(self, **kwargs):
self._supxlabel = None
self._supylabel = None

# groupers to keep track of xandy labels we want to align.
# see self.align_xlabels andself.align_ylabels and
# groupers to keep track of x, yandtitle labels we want to align.
# see self.align_xlabels,self.align_ylabels, self.align_titles 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
self._localaxes = [] # track all axes
Expand DownExpand Up@@ -1327,6 +1328,68 @@ def subplots_adjust(self, left=None, bottom=None, right=None, top=None,
ax._set_position(ax.get_subplotspec().get_position(self))
self.stale = True

def align_titles(self, axs=None):
"""
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.

If the title is on the top,
it is aligned with titles on Axes with the same top-most row.

Parameters
----------
axs : list of `~matplotlib.axes.Axes`
Optional list of (or `~numpy.ndarray`) `~matplotlib.axes.Axes`
to align the titles.
Default is to align all titles on the figure.

See Also
--------
matplotlib.figure.Figure.align_ylabels
matplotlib.figure.Figure.align_xlabels
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 aligned titles on multiple rows::

fig, axs = plt.subplots(2, 2,
subplot_kw={"xlabel": "x", "ylabel": "",
"title": "Title"})
axs[0][0].imshow(plt.np.zeros((5, 3)))
axs[0][1].imshow(plt.np.zeros((3, 5)))
axs[1][0].imshow(plt.np.zeros((2, 1)))
axs[1][1].imshow(plt.np.zeros((1, 2)))

axs[0][1].set_title('Title2', loc="left")
fig.align_titles()
"""
if axs is None:
axs = self.axes
axs = [ax for ax in np.ravel(axs) if ax.get_subplotspec() is not None]
locs = ['left', 'center', 'right']
for ax in axs:
for loc in locs:
if ax.get_title(loc=loc):
rowspan = ax.get_subplotspec().rowspan
for axc in axs:
rowspanc = axc.get_subplotspec().rowspan
if rowspan.start == rowspanc.start or \
rowspan.stop == rowspanc.stop:
self._align_label_groups['title'].join(ax, axc)

# Fixes the issue that the bbox is too small to fit the aligned
# title when saving the figure
self.canvas.draw_idle()

def align_xlabels(self, axs=None):
"""
Align the xlabels of subplots in the same subplot column if label
Expand Down
33 changes: 33 additions & 0 deletionslib/matplotlib/tests/test_figure.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,6 +11,7 @@
import numpy as np
import pytest
from PIL import Image
from matplotlib.testing.compare import compare_images

import matplotlib as mpl
from matplotlib import gridspec
Expand DownExpand Up@@ -102,6 +103,38 @@ def test_align_labels_stray_axes():
np.testing.assert_allclose(yn[::2], yn[1::2])


## TODO add image comparison
def test_align_titles():
fig, axs = plt.subplots(2, 2,
subplot_kw={"xlabel": "x", "ylabel": "",
"title": "Title"})
axs[0][0].imshow(plt.np.zeros((5, 3)))
axs[0][1].imshow(plt.np.zeros((3, 5)))
axs[1][0].imshow(plt.np.zeros((2, 1)))
axs[1][1].imshow(plt.np.zeros((1, 2)))

axs[0][1].set_title('Title2', loc="left")
fig.align_titles()
fig.savefig("./result_images/test_figure/figure_align_titles")
compare_images("./lib/matplotlib/tests/baseline_images/figure_align_titles.png",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I think we need to not use relative paths for this test

"./result_images/test_figure/figure_align_titles.png", 0)


## TODO add image comparison
@image_comparison(['figure_align_titles_param'], extensions=['png', 'svg'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The test failures that are directly related to this PR are due to the baseline images for this image comparison not being added to the repo

If it is passing locally, those two files (png, svg) should be added in thebaseline_images folder

tol=0 if platform.machine() == 'x86_64' else 0.01)
def test_align_titles_param():
fig, axs = plt.subplots(2, 2,
subplot_kw={"xlabel": "x", "ylabel": "",
"title": "t"})
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((2, 1)))
axs[1][1].imshow(plt.np.zeros((1, 2)))

fig.align_titles([axs[0][0], axs[0][1]])


def test_figure_label():
# pyplot figure creation, selection, and closing with label/number/instance
plt.close('all')
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp