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

Fix bbox of polar Axes#29051

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

Open
QuLogic wants to merge4 commits intomatplotlib:main
base:main
Choose a base branch
Loading
fromQuLogic:fix-polar-bbox
Open
Show file tree
Hide file tree
Changes fromall 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
200 changes: 127 additions & 73 deletionslib/matplotlib/projections/polar.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -426,6 +426,30 @@
axis_name = 'theta' #: Read-only name identifying the axis.
_tick_class = ThetaTick

def _update_label_position(self, renderer):
"""
Update the label position based on the bounding box enclosing
all the ticklabels and axis spine
"""
if not self._autolabelpos:
return

Check warning on line 435 in lib/matplotlib/projections/polar.py

View check run for this annotation

Codecov/ codecov/patch

lib/matplotlib/projections/polar.py#L435

Added line #L435 was not covered by tests

# get bounding boxes for this axis and any siblings
# that have been set by `fig.align_xlabels()`
xbboxes, xbboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
ybboxes, ybboxes2 = self.axes.yaxis._get_tick_boxes_siblings(renderer=renderer)
# Union with extents of the bottom spine if present, of the axes otherwise.
bbox = mtransforms.Bbox.union([
*xbboxes, *xbboxes2, *ybboxes, *ybboxes2,
self.axes.spines.get(self.label_position, self.axes).get_window_extent()])

x, y = self.label.get_position()
if self.label_position == 'bottom':
y = bbox.y0 - self.labelpad * self.get_figure(root=True).dpi / 72
else:
y = bbox.y1 + self.labelpad * self.get_figure(root=True).dpi / 72

Check warning on line 450 in lib/matplotlib/projections/polar.py

View check run for this annotation

Codecov/ codecov/patch

lib/matplotlib/projections/polar.py#L450

Added line #L450 was not covered by tests
self.label.set_position((x, y))

def _wrap_locator_formatter(self):
self.set_major_locator(ThetaLocator(self.get_major_locator()))
self.set_major_formatter(ThetaFormatter())
Expand DownExpand Up@@ -719,6 +743,30 @@
super().__init__(*args, **kwargs)
self.sticky_edges.y.append(0)

def _update_label_position(self, renderer):
"""
Update the label position based on the bounding box enclosing
all the ticklabels and axis spine
"""
if not self._autolabelpos:
return

Check warning on line 752 in lib/matplotlib/projections/polar.py

View check run for this annotation

Codecov/ codecov/patch

lib/matplotlib/projections/polar.py#L752

Added line #L752 was not covered by tests

# get bounding boxes for this axis and any siblings
# that have been set by `fig.align_xlabels()`
xbboxes, xbboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
ybboxes, ybboxes2 = self.axes.xaxis._get_tick_boxes_siblings(renderer=renderer)
# Union with extents of the linked spine if present, of the axes otherwise.
bbox = mtransforms.Bbox.union([
*xbboxes, *xbboxes2, *ybboxes, *ybboxes2,
self.axes.spines.get(self.label_position, self.axes).get_window_extent()])

x, y = self.label.get_position()
if self.label_position == 'left':
x = bbox.x0 - self.labelpad * self.get_figure(root=True).dpi / 72
else:
x = bbox.x1 + self.labelpad * self.get_figure(root=True).dpi / 72

Check warning on line 767 in lib/matplotlib/projections/polar.py

View check run for this annotation

Codecov/ codecov/patch

lib/matplotlib/projections/polar.py#L767

Added line #L767 was not covered by tests
self.label.set_position((x, y))

def _wrap_locator_formatter(self):
self.set_major_locator(RadialLocator(self.get_major_locator(),
self.axes))
Expand DownExpand Up@@ -757,6 +805,8 @@
"""
Transform (theta, r) wedge Bbox into Axes bounding box.

Additionally, this class will update the Axes patch, if set by `_set_wedge`.

Parameters
----------
center : (float, float)
Expand All@@ -771,6 +821,7 @@
self._center = center
self._viewLim = viewLim
self._originLim = originLim
self._wedge = None
self.set_children(viewLim, originLim)

__str__ = mtransforms._make_str_method("_center", "_viewLim", "_originLim")
Expand All@@ -793,21 +844,32 @@
width = min(points[1, 1] - points[0, 1], 0.5)

# Generate bounding box for wedge.
wedge = mpatches.Wedge(self._center, points[1, 1],
points[0, 0], points[1, 0],
width=width)
self.update_from_path(wedge.get_path())

# Ensure equal aspect ratio.
w, h = self._points[1] - self._points[0]
deltah = max(w - h, 0) / 2
deltaw = max(h - w, 0) / 2
self._points += np.array([[-deltaw, -deltah], [deltaw, deltah]])
if self._wedge is None:
# A PolarAxes subclass may not generate a Wedge as Axes patch and call
# _WedgeBbox._set_wedge, so use a temporary instance to calculate the
# bounds instead.
wedge = mpatches.Wedge(self._center, points[1, 1],

Check warning on line 851 in lib/matplotlib/projections/polar.py

View check run for this annotation

Codecov/ codecov/patch

lib/matplotlib/projections/polar.py#L851

Added line #L851 was not covered by tests
points[0, 0], points[1, 0],
width=width)
else:
# Update the owning Axes' patch.
wedge = self._wedge
wedge.set_center(self._center)
wedge.set_theta1(points[0, 0])
wedge.set_theta2(points[1, 0])
wedge.set_radius(points[1, 1])
wedge.set_width(width)
self.update_from_path(wedge.get_path(), ignore=True)

self._invalid = 0

return self._points

def _set_wedge(self, wedge):
"""Set the wedge patch to update when the transform changes."""
_api.check_isinstance(mpatches.Wedge, wedge=wedge)
self._wedge = wedge


class PolarAxes(Axes):
"""
Expand DownExpand Up@@ -859,8 +921,11 @@
self.spines['polar'].register_axis(self.yaxis)

def _set_lim_and_transforms(self):
# A view limit where the minimum radius can be locked if the user
# specifies an alternate origin.
# self.viewLim is set by the superclass and contains (θ, r) as its (x, y)
# components.

# This is a view limit (still in (θ, r) space) where the minimum radius can be
# locked if the user specifies an alternate origin.
self._originViewLim = mtransforms.LockableBbox(self.viewLim)

# Handle angular offset and direction.
Expand All@@ -869,30 +934,26 @@
self._theta_offset = mtransforms.Affine2D() \
.translate(self._default_theta_offset, 0.0)
self.transShift = self._direction + self._theta_offset
# A view limit shifted to the correct location after accounting for
# orientation and offset.
self._realViewLim = mtransforms.TransformedBbox(self.viewLim,
self.transShift)

# Transforms the x and y axis separately by a scale factor
# It is assumed that this part will have non-linear components
self.transScale = mtransforms.TransformWrapper(
mtransforms.IdentityTransform())

# Scale view limit into a bbox around the selected wedge. This may be
# smaller than the usual unit axes rectangle if not plotting the full
# circle.
self.axesLim = _WedgeBbox((0.5, 0.5),
self._realViewLim, self._originViewLim)

# Scale the wedge to fill the axes.
# This is a view limit in (θ, r) shifted to the correct location after
# accounting for θ orientation and offset.
self._realViewLim = mtransforms.TransformedBbox(self.viewLim, self.transShift)

# Transforms the θ and r axis separately by a scale factor. It is assumed that
# this part will have the non-linear components.
self.transScale = mtransforms.TransformWrapper(mtransforms.IdentityTransform())

# Scale view limit into a bbox around the selected wedge. This may be smaller
# than the usual unit axes rectangle if not plotting the full circle.
self.axesLim = _WedgeBbox((0.5, 0.5), self._realViewLim, self._originViewLim)

# Scale the wedge to fill the Axes unit space.
self.transWedge = mtransforms.BboxTransformFrom(self.axesLim)

# Scale theaxesto fill thefigure.
# Scale theAxes unit spaceto fill theAxes actual position.
self.transAxes = mtransforms.BboxTransformTo(self.bbox)

# A (possibly non-linear) projection on the (already scaled)
#data. This one isaware of rmin
# A (possibly non-linear) projection on the (already scaled) data. This one is
# aware of rmin.
self.transProjection = self.PolarTransform(
self,
apply_theta_transforms=False,
Expand All@@ -901,52 +962,48 @@
# Add dependency on rorigin.
self.transProjection.set_children(self._originViewLim)

# An affine transformation on the data, generally to limit the
# range of the axes
# An affine transformation on the data, generally to limit the range of the axes
self.transProjectionAffine = self.PolarAffine(self.transScale,
self._originViewLim)

# The complete data transformation stack -- from data all the
# way to display coordinates
#
# 1. Remove any radial axis scaling (e.g. log scaling)
# 2. Shift data in the theta direction
# 3. Project the data from polar to cartesian values
# (with the origin in the same place)
# 4. Scale and translate the cartesian values to Axes coordinates
# (here the origin is moved to the lower left of the Axes)
# 5. Move and scale to fill the Axes
# 6. Convert from Axes coordinates to Figure coordinates
# The complete data transformation stack -- from data all the way to display
# coordinates.
self.transData = (
# 1. Remove any radial axis scaling (e.g. log scaling).
self.transScale +
# 2. Shift data in the θ direction.
self.transShift +
# 3. Project the data from polar to cartesian values (with the origin in the
# same place).
self.transProjection +
(
# 4. Scale and translate the cartesian values to Axes coordinates (here
# the origin is moved to the lower left of the Axes).
self.transProjectionAffine +
# 5. Move and scale to fill the Axes.
self.transWedge +
# 6. Convert from Axes coordinates to Figure coordinates.
self.transAxes
)
)

# This is the transform for theta-axis ticks. It is
# equivalent to transData, except it always puts r == 0.0 and r == 1.0
# at the edge of the axis circles.
# This is the transform for θ-axis ticks. It is equivalent to transData, except
# it always puts r == 0.0 and r == 1.0 at the edge of the axis circles.
self._xaxis_transform = (
mtransforms.blended_transform_factory(
mtransforms.IdentityTransform(),
mtransforms.BboxTransformTo(self.viewLim)) +
self.transData)
# Thetheta labels are flipped along the radius, so that text 1 is on
#the outside bydefault. This should work the same as before.
# Theθ labels are flipped along the radius, so that text 1 is on the outside by
# default. This should work the same as before.
flipr_transform = mtransforms.Affine2D() \
.translate(0.0, -0.5) \
.scale(1.0, -1.0) \
.translate(0.0, 0.5)
self._xaxis_text_transform = flipr_transform + self._xaxis_transform

# This is the transform for r-axis ticks. It scales the theta
# axis so the gridlines from 0.0 to 1.0, now go from thetamin to
# thetamax.
# This is the transform for r-axis ticks. It scales the θ-axis so the gridlines
# from 0.0 to 1.0, now go from thetamin to thetamax.
self._yaxis_transform = (
mtransforms.blended_transform_factory(
mtransforms.BboxTransformTo(self.viewLim),
Expand DownExpand Up@@ -999,31 +1056,16 @@

def draw(self, renderer):
self._unstale_viewLim()
thetamin, thetamax = np.rad2deg(self._realViewLim.intervalx)
if thetamin > thetamax:
thetamin, thetamax = thetamax, thetamin
rmin, rmax = ((self._realViewLim.intervaly - self.get_rorigin()) *
self.get_rsign())
self.axesLim.get_points() # Unstale bbox and Axes patch.
self.set_aspect(self.axesLim.height / self.axesLim.width)
if isinstance(self.patch, mpatches.Wedge):
# Backwards-compatibility: Any subclassed Axes might override the
# patch to not be the Wedge that PolarAxes uses.
center = self.transWedge.transform((0.5, 0.5))
self.patch.set_center(center)
self.patch.set_theta1(thetamin)
self.patch.set_theta2(thetamax)

edge, _ = self.transWedge.transform((1, 0))
radius = edge - center[0]
width = min(radius * (rmax - rmin) / rmax, radius)
self.patch.set_radius(radius)
self.patch.set_width(width)

inner_width = radius - width
inner = self.spines.get('inner', None)
if inner:
inner.set_visible(inner_width !=0.0)
inner.set_visible(self.patch.r !=self.patch.width)

visible = not_is_full_circle_deg(thetamin, thetamax)
visible = not_is_full_circle_rad(*self._realViewLim.intervalx)
# For backwards compatibility, any subclassed Axes might override the
# spines to not include start/end that PolarAxes uses.
start = self.spines.get('start', None)
Expand All@@ -1043,8 +1085,20 @@

super().draw(renderer)

def _wedge_get_patch_transform(self):
# See _gen_axes_patch for the use of this function. It's not a lambda or nested
# function to not break pickling.
return self.transWedge

def _gen_axes_patch(self):
return mpatches.Wedge((0.5, 0.5), 0.5, 0.0, 360.0)
wedge = mpatches.Wedge((0.5, 0.5), 0.5, 0.0, 360.0)
self.axesLim._set_wedge(wedge)
# The caller of this function will set the wedge's transform directly to
# `self.transAxes`, but `self.axesLim` will update to a pre-`self.transWedge`
# coordinate space, so override the patch transform (which is otherwise always
# an identity transform) to get the wedge in the right coordinate space.
wedge.get_patch_transform = self._wedge_get_patch_transform
return wedge

def _gen_axes_spines(self):
spines = {
Expand Down
View file
Open in desktop
Binary file not shown.
View file
Open in desktop
Loading
Sorry, something went wrong.Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp