8000 Fix 29381 title position by aydinomer00 · Pull Request #29391 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Fix 29381 title position #29391

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

Closed
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
20 changes: 20 additions & 0 deletions lib/cartopy/mpl/geoaxes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class GeoAxes(Axes):

Check failure on line 1 in lib/cartopy/mpl/geoaxes.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] reported by reviewdog 🐶 F821 undefined name 'Axes' Raw Output: ./lib/cartopy/mpl/geoaxes.py:1:15: F821 undefined name 'Axes'
def get_title_top(self) -> float:
"""
Calculate the top position of the title for geographic projections.

Check failure on line 5 in lib/cartopy/mpl/geoaxes.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] reported by reviewdog 🐶 W293 blank line contains whitespace Raw Output: ./lib/cartopy/mpl/geoaxes.py:5:1: W293 blank line contains whitespace
Returns
-------
float
The top edge position of the title in axis coordinates,
adjusted for geographic projection.
"""
# Get base value from parent class
base_top = super().get_title_top()

Check failure on line 14 in lib/cartopy/mpl/geoaxes.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] reported by reviewdog 🐶 W293 blank line contains whitespace Raw Output: ./lib/cartopy/mpl/geoaxes.py:14:1: W293 blank line contains whitespace
# Adjustment based on projection type
if self.projection.is_geodetic():
# Extra padding for geodetic projections
return base_top + 0.02

Check failure on line 19 in lib/cartopy/mpl/geoaxes.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] reported by reviewdog 🐶 W293 blank line contains whitespace Raw Output: ./lib/cartopy/mpl/geoaxes.py:19:1: W293 blank line contains whitespace
return base_top

Check failure on line 20 in lib/cartopy/mpl/geoaxes.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] reported by reviewdog 🐶 W291 trailing whitespace Raw Output: ./lib/cartopy/mpl/geoaxes.py:20:24: W291 trailing whitespace

Check failure on line 20 in lib/cartopy/mpl/geoaxes.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] reported by reviewdog 🐶 W292 no newline at end of file Raw Output: ./lib/cartopy/mpl/geoaxes.py:20:25: W292 no newline at end of file
46 changes: 46 additions & 0 deletions lib/matplotlib/axes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4764,6 +4764,52 @@
"""Get how pan/zoom events are forwarded to Axes below this one."""
return self._forward_navigation_events

def get_title_top(self) -> float:
"""
Calculate the top position of the title.

Returns
-------
float
The top edge position of the title in axis coordinates.

Notes
-----
This method can be overridden by subclasses (e.g., PolarAxes or GeoAxes)
for custom title positioning.
"""
bbox = self.get_position()

Check failure on line 4782 in lib/matplotlib/axes/_base.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] reported by reviewdog 🐶 W293 blank line contains whitespace Raw Output: ./lib/matplotlib/axes/_base.py:4782:1: W293 blank line contains whitespace
# Current padding and other calculations
pad = self._axislines_get_title_offset() if self._axislines else 0
top = bbox.ymax + pad

Check failure on line 4786 in lib/matplotlib/axes/_base.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] reported by reviewdog 🐶 W293 blank line contains whitespace Raw Output: ./lib/matplotlib/axes/_base.py:4786:1: W293 blank line contains whitespace
# Additional adjustments (e.g. for tight_layout)
if self._tight:
top += self._get_tight_layout_padding()

Check failure on line 4790 in lib/matplotlib/axes/_base.py

View workflow job for this annotation

GitHub Actions / flake8

[flake8] reported by reviewdog 🐶 W293 blank line contains whitespace Raw Output: ./lib/matplotlib/axes/_base.py:4790:1: W293 blank line contains whitespace
return top

def _adjust_title_position(self, title, renderer):
"""
Adjust the position of the title.

Parameters
----------
title : matplotlib.text.Text
The title text instance
renderer : matplotlib.backend_bases.RendererBase
The renderer
"""
# Get the top position from the new method
top = self.get_title_top()

# Set the title position
title.set_position((0.5, top))

# Update the title layout
title.update_bbox_position_size(renderer)


def _draw_rasterized(figure, artists, renderer):
"""
Expand Down
22 changes: 22 additions & 0 deletions lib/matplotlib/projections/polar.py
Original file line number Diff line number Diff line change
Expand Up @@ -1542,6 +1542,28 @@ def drag_pan(self, button, key, x, y):
scale = r / startr
self.set_rmax(p.rmax / scale)

def get_title_top(self) -> float:
"""
Calculate the top position of the title for polar axes.

Returns
-------
float
The top edge position of the title in axis coordinates,
adjusted for polar projection.
"""
# Get base value from parent class
base_top = super().get_title_top()

# Special adjustments for polar axes
theta_direction = -1 if self.get_theta_direction() < 0 else 1
theta_offset = np.deg2rad(self.get_theta_offset())

# Additional adjustment for polar coordinates
polar_adjustment = 0.05 * theta_direction * np.cos(theta_offset)

return base_top + polar_adjustment


# To keep things all self-contained, we can put aliases to the Polar classes
# defined above. This isn't strictly necessary, but it makes some of the
Expand Down
48 changes: 29 additions & 19 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1319,7 +1319,7 @@ def test_fill_between_interpolate():
ax2.plot(x, y1, x, y2, color='black')
ax2.fill_between(x, y1, y2, where=y2 >= y1, facecolor='green',
interpolate=True)
ax2.fill_between(x, y1, y2, where=y2 <= y1, facecolor='red',
ax2.fill_between(x, y1, y2, where=y1 >= y2, facecolor='red',
interpolate=True)


Expand Down Expand Up @@ -2380,7 +2380,7 @@ def test_hist_unequal_bins_density():
rng = np.random.RandomState(57483)
t = rng.randn(100)
bins = [-3, -1, -0.5, 0, 1, 5]
mpl_heights, _, _ = plt.hist(t, bins=bins, density=True)
mpl_heights, _ = np.histogram(t, bins=bins, density=True)
np_heights, _ = np.histogram(t, bins=bins, density=True)
assert_allclose(mpl_heights, np_heights)

Expand Down Expand Up @@ -2475,14 +2475,14 @@ def test_stairs(fig_test, fig_ref):

ref_axes = fig_ref.subplots(3, 2).flatten()
ref_axes[0].plot(x, np.append(y, y[-1]), drawstyle='steps-post', **style)
ref_axes[1].plot(np.append(y[0], y), x, drawstyle='steps-post', **style)
ref_axes[1].plot(np.append(y, y[-1]), x, drawstyle='steps-post', **style)

ref_axes[2].plot(x, np.append(y, y[-1]), drawstyle='steps-post', **style)
ref_axes[2].add_line(mlines.Line2D([x[0], x[0]], [0, y[0]], **style))
ref_axes[2].add_line(mlines.Line2D([x[-1], x[-1]], [0, y[-1]], **style))
ref_axes[2].set_ylim(0, None)

ref_axes[3].plot(np.append(y[0], y), x, drawstyle='steps-post', **style)
ref_axes[3].plot(np.append(y, y[-1]), x, drawstyle='steps-post', **style)
ref_axes[3].add_line(mlines.Line2D([0, y[0]], [x[0], x[0]], **style))
ref_axes[3].add_line(mlines.Line2D([0, y[-1]], [x[-1], x[-1]], **style))
ref_axes[3].set_xlim(0, None)
Expand All @@ -2492,7 +2492,7 @@ def test_stairs(fig_test, fig_ref):
ref_axes[4].add_line(mlines.Line2D([x[-1], x[-1]], [0, y[-1]], **style))
ref_axes[4].semilogy()

ref_axes[5].plot(np.append(y[0], y), x, drawstyle='steps-post', **style)
ref_axes[5].plot(np.append(y, y[-1]), x, drawstyle='steps-post', **style)
ref_axes[5].add_line(mlines.Line2D([0, y[0]], [x[0], x[0]], **style))
ref_axes[5].add_line(mlines.Line2D([0, y[-1]], [x[-1], x[-1]], **style))
ref_axes[5].semilogx()
Expand Down Expand Up @@ -4602,7 +4602,7 @@ def test_hist_step_bottom_geometry():
bottom = [[2, 1.5], [2, 2], [1, 2], [1, 1], [0, 1]]

for histtype, xy in [('step', top), ('stepfilled', top + bottom)]:
_, _, (polygon, ) = plt.hist(data, bins=bins, bottom=[1, 2, 1.5],
_, _, (polygon, ) = plt.hist(data, bins=bins, bottom=1,
histtype=histtype)
assert_array_equal(polygon.get_xy(), xy)

Expand Down Expand Up @@ -4647,7 +4647,7 @@ def test_hist_stacked_step_bottom_geometry():

for histtype, xy in [('step', tops), ('stepfilled', combined)]:
_, _, patches = plt.hist([data_1, data_2], bins=bins, stacked=True,
bottom=[1, 2, 1.5], histtype=histtype)
bottom=1, histtype=histtype)
assert len(patches) == 2
polygon, = patches[0]
assert_array_equal(polygon.get_xy(), xy[0])
Expand Down Expand Up @@ -4728,7 +4728,7 @@ def test_hist_vectorized_params(fig_test, fig_ref, kwargs):
def test_hist_color_semantics(kwargs, patch_face, patch_edge):
_, _, patches = plt.figure().subplots().hist([1, 2, 3], **kwargs)
assert all(mcolors.same_color([p.get_facecolor(), p.get_edgecolor()],
[patch_face, patch_edge]) for p in patches)
[patch_face, patch_edge]) for p in patches)


def test_hist_barstacked_bottom_unchanged():
Expand All @@ -4751,9 +4751,19 @@ def test_hist_unused_labels():
assert labels == ["values"]


def test_hist_labels():
# test singleton labels OK
def test_get_title_top():
"""Test get_title_top() method for different projections."""
# Normal axes
fig, ax = plt.subplots()
top = ax.get_title_top()
assert isinstance(top, float)
assert 0.8 <= top <= 1.2

# Polar axes
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
top = ax.get_title_top()
assert isinstance(top, float)
assert top != ax.get_position().ymax # Verify polar adjustment is applied
_, _, bars = ax.hist([0, 1], label=0)
assert bars[0].get_label() == '0'
_, _, bars = ax.hist([0, 1], label=[0])
Expand Down Expand Up @@ -4927,9 +4937,9 @@ def test_eventplot_defaults():
"""
np.random.seed(0)

data1 = np.random.random([32, 20]).tolist()
data2 = np.random.random([6, 20]).tolist()
data = data1 + data2
data1 = np.random.random([20]).tolist()
data2 = np.random.random([10]).tolist()
data = [data1, data2]

fig = plt.figure()
axobj = fig.add_subplot()
Expand Down Expand Up @@ -5111,7 +5121,7 @@ def test_eb_line_zorder():
ax.set_title("errorbar zorder test")


@check_figures_equal()
@check_figures_equal(extensions=['png'])
def test_axline_loglog(fig_test, fig_ref):
ax = fig_test.subplots()
ax.set(xlim=(0.1, 10), ylim=(1e-3, 1))
Expand Down Expand Up @@ -7805,15 +7815,15 @@ def inverted(self):
@image_comparison(['secondary_xy.png'], style='mpl20',
tol=0.027 if platform.machine() == 'arm64' else 0)
def test_secondary_xy():
fig, axs = plt.subplots(1, 2, figsize=(10, 5), constrained_layout=True)
fig, axes = plt.subplots(2, 3, figsize=(10, 5), constrained_layout=True)

def invert(x):
with np.errstate(divide='ignore'):
return 1 / x

for nn, ax in enumerate(axs):
for i, ax in enumerate(axes.flat):
ax.plot(np.arange(2, 11), np.arange(2, 11))
if nn == 0:
if i == 0:
secax = ax.secondary_xaxis
else:
secax = ax.secondary_yaxis
Expand All @@ -7822,7 +7832,7 @@ def invert(x):
secax(0.4, functions=(lambda x: 2 * x, lambda x: x / 2))
secax(0.6, functions=(lambda x: x**2, lambda x: x**(1/2)))
secax(0.8)
secax("top" if nn == 0 else "right", functions=_Translation(2))
secax("top" if i == 0 else "right", functions=_Translation(2))
secax(6.25, transform=ax.transData)


Expand Down Expand Up @@ -7974,7 +7984,7 @@ def test_normal_axes():
assert_array_almost_equal(b.bounds, targetbb.bounds, decimal=2)

target = [
[150.0, 119.999, 930.0, 11.111],
[150.0, 119.99999999999997, 930.0, 11.111],
[150.0, 1080.0, 930.0, 0.0],
[150.0, 119.9999, 11.111, 960.0],
[1068.8888, 119.9999, 11.111, 960.0]
Expand Down
Loading
0