up follow livre

This commit is contained in:
Tykayn 2025-08-30 18:14:14 +02:00 committed by tykayn
parent b4b4398bb0
commit 3a7a3849ae
12242 changed files with 2564461 additions and 6914 deletions

View file

@ -0,0 +1,126 @@
"""
Non-separable transforms that map from data space to screen space.
Projections are defined as `~.axes.Axes` subclasses. They include the
following elements:
- A transformation from data coordinates into display coordinates.
- An inverse of that transformation. This is used, for example, to convert
mouse positions from screen space back into data space.
- Transformations for the gridlines, ticks and ticklabels. Custom projections
will often need to place these elements in special locations, and Matplotlib
has a facility to help with doing so.
- Setting up default values (overriding `~.axes.Axes.cla`), since the defaults
for a rectilinear Axes may not be appropriate.
- Defining the shape of the Axes, for example, an elliptical Axes, that will be
used to draw the background of the plot and for clipping any data elements.
- Defining custom locators and formatters for the projection. For example, in
a geographic projection, it may be more convenient to display the grid in
degrees, even if the data is in radians.
- Set up interactive panning and zooming. This is left as an "advanced"
feature left to the reader, but there is an example of this for polar plots
in `matplotlib.projections.polar`.
- Any additional methods for additional convenience or features.
Once the projection Axes is defined, it can be used in one of two ways:
- By defining the class attribute ``name``, the projection Axes can be
registered with `matplotlib.projections.register_projection` and subsequently
simply invoked by name::
fig.add_subplot(projection="my_proj_name")
- For more complex, parameterisable projections, a generic "projection" object
may be defined which includes the method ``_as_mpl_axes``. ``_as_mpl_axes``
should take no arguments and return the projection's Axes subclass and a
dictionary of additional arguments to pass to the subclass' ``__init__``
method. Subsequently a parameterised projection can be initialised with::
fig.add_subplot(projection=MyProjection(param1=param1_value))
where MyProjection is an object which implements a ``_as_mpl_axes`` method.
A full-fledged and heavily annotated example is in
:doc:`/gallery/misc/custom_projection`. The polar plot functionality in
`matplotlib.projections.polar` may also be of interest.
"""
from .. import axes, _docstring
from .geo import AitoffAxes, HammerAxes, LambertAxes, MollweideAxes
from .polar import PolarAxes
try:
from mpl_toolkits.mplot3d import Axes3D
except Exception:
import warnings
warnings.warn("Unable to import Axes3D. This may be due to multiple versions of "
"Matplotlib being installed (e.g. as a system package and as a pip "
"package). As a result, the 3D projection is not available.")
Axes3D = None
class ProjectionRegistry:
"""A mapping of registered projection names to projection classes."""
def __init__(self):
self._all_projection_types = {}
def register(self, *projections):
"""Register a new set of projections."""
for projection in projections:
name = projection.name
self._all_projection_types[name] = projection
def get_projection_class(self, name):
"""Get a projection class from its *name*."""
return self._all_projection_types[name]
def get_projection_names(self):
"""Return the names of all projections currently registered."""
return sorted(self._all_projection_types)
projection_registry = ProjectionRegistry()
projection_registry.register(
axes.Axes,
PolarAxes,
AitoffAxes,
HammerAxes,
LambertAxes,
MollweideAxes,
)
if Axes3D is not None:
projection_registry.register(Axes3D)
else:
# remove from namespace if not importable
del Axes3D
def register_projection(cls):
projection_registry.register(cls)
def get_projection_class(projection=None):
"""
Get a projection class from its name.
If *projection* is None, a standard rectilinear projection is returned.
"""
if projection is None:
projection = 'rectilinear'
try:
return projection_registry.get_projection_class(projection)
except KeyError as err:
raise ValueError("Unknown projection %r" % projection) from err
get_projection_names = projection_registry.get_projection_names
_docstring.interpd.register(projection_names=get_projection_names())

View file

@ -0,0 +1,20 @@
from .geo import (
AitoffAxes as AitoffAxes,
HammerAxes as HammerAxes,
LambertAxes as LambertAxes,
MollweideAxes as MollweideAxes,
)
from .polar import PolarAxes as PolarAxes
from ..axes import Axes
class ProjectionRegistry:
def __init__(self) -> None: ...
def register(self, *projections: type[Axes]) -> None: ...
def get_projection_class(self, name: str) -> type[Axes]: ...
def get_projection_names(self) -> list[str]: ...
projection_registry: ProjectionRegistry
def register_projection(cls: type[Axes]) -> None: ...
def get_projection_class(projection: str | None = ...) -> type[Axes]: ...
def get_projection_names() -> list[str]: ...

View file

@ -0,0 +1,511 @@
import numpy as np
import matplotlib as mpl
from matplotlib import _api
from matplotlib.axes import Axes
import matplotlib.axis as maxis
from matplotlib.patches import Circle
from matplotlib.path import Path
import matplotlib.spines as mspines
from matplotlib.ticker import (
Formatter, NullLocator, FixedLocator, NullFormatter)
from matplotlib.transforms import Affine2D, BboxTransformTo, Transform
class GeoAxes(Axes):
"""An abstract base class for geographic projections."""
class ThetaFormatter(Formatter):
"""
Used to format the theta tick labels. Converts the native
unit of radians into degrees and adds a degree symbol.
"""
def __init__(self, round_to=1.0):
self._round_to = round_to
def __call__(self, x, pos=None):
degrees = round(np.rad2deg(x) / self._round_to) * self._round_to
return f"{degrees:0.0f}\N{DEGREE SIGN}"
RESOLUTION = 75
def _init_axis(self):
self.xaxis = maxis.XAxis(self, clear=False)
self.yaxis = maxis.YAxis(self, clear=False)
self.spines['geo'].register_axis(self.yaxis)
def clear(self):
# docstring inherited
super().clear()
self.set_longitude_grid(30)
self.set_latitude_grid(15)
self.set_longitude_grid_ends(75)
self.xaxis.set_minor_locator(NullLocator())
self.yaxis.set_minor_locator(NullLocator())
self.xaxis.set_ticks_position('none')
self.yaxis.set_ticks_position('none')
self.yaxis.set_tick_params(label1On=True)
# Why do we need to turn on yaxis tick labels, but
# xaxis tick labels are already on?
self.grid(mpl.rcParams['axes.grid'])
Axes.set_xlim(self, -np.pi, np.pi)
Axes.set_ylim(self, -np.pi / 2.0, np.pi / 2.0)
def _set_lim_and_transforms(self):
# A (possibly non-linear) projection on the (already scaled) data
self.transProjection = self._get_core_transform(self.RESOLUTION)
self.transAffine = self._get_affine_transform()
self.transAxes = BboxTransformTo(self.bbox)
# The complete data transformation stack -- from data all the
# way to display coordinates
self.transData = \
self.transProjection + \
self.transAffine + \
self.transAxes
# This is the transform for longitude ticks.
self._xaxis_pretransform = \
Affine2D() \
.scale(1, self._longitude_cap * 2) \
.translate(0, -self._longitude_cap)
self._xaxis_transform = \
self._xaxis_pretransform + \
self.transData
self._xaxis_text1_transform = \
Affine2D().scale(1, 0) + \
self.transData + \
Affine2D().translate(0, 4)
self._xaxis_text2_transform = \
Affine2D().scale(1, 0) + \
self.transData + \
Affine2D().translate(0, -4)
# This is the transform for latitude ticks.
yaxis_stretch = Affine2D().scale(np.pi * 2, 1).translate(-np.pi, 0)
yaxis_space = Affine2D().scale(1, 1.1)
self._yaxis_transform = \
yaxis_stretch + \
self.transData
yaxis_text_base = \
yaxis_stretch + \
self.transProjection + \
(yaxis_space +
self.transAffine +
self.transAxes)
self._yaxis_text1_transform = \
yaxis_text_base + \
Affine2D().translate(-8, 0)
self._yaxis_text2_transform = \
yaxis_text_base + \
Affine2D().translate(8, 0)
def _get_affine_transform(self):
transform = self._get_core_transform(1)
xscale, _ = transform.transform((np.pi, 0))
_, yscale = transform.transform((0, np.pi/2))
return Affine2D() \
.scale(0.5 / xscale, 0.5 / yscale) \
.translate(0.5, 0.5)
def get_xaxis_transform(self, which='grid'):
_api.check_in_list(['tick1', 'tick2', 'grid'], which=which)
return self._xaxis_transform
def get_xaxis_text1_transform(self, pad):
return self._xaxis_text1_transform, 'bottom', 'center'
def get_xaxis_text2_transform(self, pad):
return self._xaxis_text2_transform, 'top', 'center'
def get_yaxis_transform(self, which='grid'):
_api.check_in_list(['tick1', 'tick2', 'grid'], which=which)
return self._yaxis_transform
def get_yaxis_text1_transform(self, pad):
return self._yaxis_text1_transform, 'center', 'right'
def get_yaxis_text2_transform(self, pad):
return self._yaxis_text2_transform, 'center', 'left'
def _gen_axes_patch(self):
return Circle((0.5, 0.5), 0.5)
def _gen_axes_spines(self):
return {'geo': mspines.Spine.circular_spine(self, (0.5, 0.5), 0.5)}
def set_yscale(self, *args, **kwargs):
if args[0] != 'linear':
raise NotImplementedError
set_xscale = set_yscale
def set_xlim(self, *args, **kwargs):
"""Not supported. Please consider using Cartopy."""
raise TypeError("Changing axes limits of a geographic projection is "
"not supported. Please consider using Cartopy.")
set_ylim = set_xlim
set_xbound = set_xlim
set_ybound = set_ylim
def invert_xaxis(self):
"""Not supported. Please consider using Cartopy."""
raise TypeError("Changing axes limits of a geographic projection is "
"not supported. Please consider using Cartopy.")
invert_yaxis = invert_xaxis
def format_coord(self, lon, lat):
"""Return a format string formatting the coordinate."""
lon, lat = np.rad2deg([lon, lat])
ns = 'N' if lat >= 0.0 else 'S'
ew = 'E' if lon >= 0.0 else 'W'
return ('%f\N{DEGREE SIGN}%s, %f\N{DEGREE SIGN}%s'
% (abs(lat), ns, abs(lon), ew))
def set_longitude_grid(self, degrees):
"""
Set the number of degrees between each longitude grid.
"""
# Skip -180 and 180, which are the fixed limits.
grid = np.arange(-180 + degrees, 180, degrees)
self.xaxis.set_major_locator(FixedLocator(np.deg2rad(grid)))
self.xaxis.set_major_formatter(self.ThetaFormatter(degrees))
def set_latitude_grid(self, degrees):
"""
Set the number of degrees between each latitude grid.
"""
# Skip -90 and 90, which are the fixed limits.
grid = np.arange(-90 + degrees, 90, degrees)
self.yaxis.set_major_locator(FixedLocator(np.deg2rad(grid)))
self.yaxis.set_major_formatter(self.ThetaFormatter(degrees))
def set_longitude_grid_ends(self, degrees):
"""
Set the latitude(s) at which to stop drawing the longitude grids.
"""
self._longitude_cap = np.deg2rad(degrees)
self._xaxis_pretransform \
.clear() \
.scale(1.0, self._longitude_cap * 2.0) \
.translate(0.0, -self._longitude_cap)
def get_data_ratio(self):
"""Return the aspect ratio of the data itself."""
return 1.0
### Interactive panning
def can_zoom(self):
"""
Return whether this Axes supports the zoom box button functionality.
This Axes object does not support interactive zoom box.
"""
return False
def can_pan(self):
"""
Return whether this Axes supports the pan/zoom button functionality.
This Axes object does not support interactive pan/zoom.
"""
return False
def start_pan(self, x, y, button):
pass
def end_pan(self):
pass
def drag_pan(self, button, key, x, y):
pass
class _GeoTransform(Transform):
# Factoring out some common functionality.
input_dims = output_dims = 2
def __init__(self, resolution):
"""
Create a new geographical transform.
Resolution is the number of steps to interpolate between each input
line segment to approximate its path in curved space.
"""
super().__init__()
self._resolution = resolution
def __str__(self):
return f"{type(self).__name__}({self._resolution})"
def transform_path_non_affine(self, path):
# docstring inherited
ipath = path.interpolated(self._resolution)
return Path(self.transform(ipath.vertices), ipath.codes)
class AitoffAxes(GeoAxes):
name = 'aitoff'
class AitoffTransform(_GeoTransform):
"""The base Aitoff transform."""
def transform_non_affine(self, values):
# docstring inherited
longitude, latitude = values.T
# Pre-compute some values
half_long = longitude / 2.0
cos_latitude = np.cos(latitude)
alpha = np.arccos(cos_latitude * np.cos(half_long))
sinc_alpha = np.sinc(alpha / np.pi) # np.sinc is sin(pi*x)/(pi*x).
x = (cos_latitude * np.sin(half_long)) / sinc_alpha
y = np.sin(latitude) / sinc_alpha
return np.column_stack([x, y])
def inverted(self):
# docstring inherited
return AitoffAxes.InvertedAitoffTransform(self._resolution)
class InvertedAitoffTransform(_GeoTransform):
def transform_non_affine(self, values):
# docstring inherited
# MGDTODO: Math is hard ;(
return np.full_like(values, np.nan)
def inverted(self):
# docstring inherited
return AitoffAxes.AitoffTransform(self._resolution)
def __init__(self, *args, **kwargs):
self._longitude_cap = np.pi / 2.0
super().__init__(*args, **kwargs)
self.set_aspect(0.5, adjustable='box', anchor='C')
self.clear()
def _get_core_transform(self, resolution):
return self.AitoffTransform(resolution)
class HammerAxes(GeoAxes):
name = 'hammer'
class HammerTransform(_GeoTransform):
"""The base Hammer transform."""
def transform_non_affine(self, values):
# docstring inherited
longitude, latitude = values.T
half_long = longitude / 2.0
cos_latitude = np.cos(latitude)
sqrt2 = np.sqrt(2.0)
alpha = np.sqrt(1.0 + cos_latitude * np.cos(half_long))
x = (2.0 * sqrt2) * (cos_latitude * np.sin(half_long)) / alpha
y = (sqrt2 * np.sin(latitude)) / alpha
return np.column_stack([x, y])
def inverted(self):
# docstring inherited
return HammerAxes.InvertedHammerTransform(self._resolution)
class InvertedHammerTransform(_GeoTransform):
def transform_non_affine(self, values):
# docstring inherited
x, y = values.T
z = np.sqrt(1 - (x / 4) ** 2 - (y / 2) ** 2)
longitude = 2 * np.arctan((z * x) / (2 * (2 * z ** 2 - 1)))
latitude = np.arcsin(y*z)
return np.column_stack([longitude, latitude])
def inverted(self):
# docstring inherited
return HammerAxes.HammerTransform(self._resolution)
def __init__(self, *args, **kwargs):
self._longitude_cap = np.pi / 2.0
super().__init__(*args, **kwargs)
self.set_aspect(0.5, adjustable='box', anchor='C')
self.clear()
def _get_core_transform(self, resolution):
return self.HammerTransform(resolution)
class MollweideAxes(GeoAxes):
name = 'mollweide'
class MollweideTransform(_GeoTransform):
"""The base Mollweide transform."""
def transform_non_affine(self, values):
# docstring inherited
def d(theta):
delta = (-(theta + np.sin(theta) - pi_sin_l)
/ (1 + np.cos(theta)))
return delta, np.abs(delta) > 0.001
longitude, latitude = values.T
clat = np.pi/2 - np.abs(latitude)
ihigh = clat < 0.087 # within 5 degrees of the poles
ilow = ~ihigh
aux = np.empty(latitude.shape, dtype=float)
if ilow.any(): # Newton-Raphson iteration
pi_sin_l = np.pi * np.sin(latitude[ilow])
theta = 2.0 * latitude[ilow]
delta, large_delta = d(theta)
while np.any(large_delta):
theta[large_delta] += delta[large_delta]
delta, large_delta = d(theta)
aux[ilow] = theta / 2
if ihigh.any(): # Taylor series-based approx. solution
e = clat[ihigh]
d = 0.5 * (3 * np.pi * e**2) ** (1.0/3)
aux[ihigh] = (np.pi/2 - d) * np.sign(latitude[ihigh])
xy = np.empty(values.shape, dtype=float)
xy[:, 0] = (2.0 * np.sqrt(2.0) / np.pi) * longitude * np.cos(aux)
xy[:, 1] = np.sqrt(2.0) * np.sin(aux)
return xy
def inverted(self):
# docstring inherited
return MollweideAxes.InvertedMollweideTransform(self._resolution)
class InvertedMollweideTransform(_GeoTransform):
def transform_non_affine(self, values):
# docstring inherited
x, y = values.T
# from Equations (7, 8) of
# https://mathworld.wolfram.com/MollweideProjection.html
theta = np.arcsin(y / np.sqrt(2))
longitude = (np.pi / (2 * np.sqrt(2))) * x / np.cos(theta)
latitude = np.arcsin((2 * theta + np.sin(2 * theta)) / np.pi)
return np.column_stack([longitude, latitude])
def inverted(self):
# docstring inherited
return MollweideAxes.MollweideTransform(self._resolution)
def __init__(self, *args, **kwargs):
self._longitude_cap = np.pi / 2.0
super().__init__(*args, **kwargs)
self.set_aspect(0.5, adjustable='box', anchor='C')
self.clear()
def _get_core_transform(self, resolution):
return self.MollweideTransform(resolution)
class LambertAxes(GeoAxes):
name = 'lambert'
class LambertTransform(_GeoTransform):
"""The base Lambert transform."""
def __init__(self, center_longitude, center_latitude, resolution):
"""
Create a new Lambert transform. Resolution is the number of steps
to interpolate between each input line segment to approximate its
path in curved Lambert space.
"""
_GeoTransform.__init__(self, resolution)
self._center_longitude = center_longitude
self._center_latitude = center_latitude
def transform_non_affine(self, values):
# docstring inherited
longitude, latitude = values.T
clong = self._center_longitude
clat = self._center_latitude
cos_lat = np.cos(latitude)
sin_lat = np.sin(latitude)
diff_long = longitude - clong
cos_diff_long = np.cos(diff_long)
inner_k = np.maximum( # Prevent divide-by-zero problems
1 + np.sin(clat)*sin_lat + np.cos(clat)*cos_lat*cos_diff_long,
1e-15)
k = np.sqrt(2 / inner_k)
x = k * cos_lat*np.sin(diff_long)
y = k * (np.cos(clat)*sin_lat - np.sin(clat)*cos_lat*cos_diff_long)
return np.column_stack([x, y])
def inverted(self):
# docstring inherited
return LambertAxes.InvertedLambertTransform(
self._center_longitude,
self._center_latitude,
self._resolution)
class InvertedLambertTransform(_GeoTransform):
def __init__(self, center_longitude, center_latitude, resolution):
_GeoTransform.__init__(self, resolution)
self._center_longitude = center_longitude
self._center_latitude = center_latitude
def transform_non_affine(self, values):
# docstring inherited
x, y = values.T
clong = self._center_longitude
clat = self._center_latitude
p = np.maximum(np.hypot(x, y), 1e-9)
c = 2 * np.arcsin(0.5 * p)
sin_c = np.sin(c)
cos_c = np.cos(c)
latitude = np.arcsin(cos_c*np.sin(clat) +
((y*sin_c*np.cos(clat)) / p))
longitude = clong + np.arctan(
(x*sin_c) / (p*np.cos(clat)*cos_c - y*np.sin(clat)*sin_c))
return np.column_stack([longitude, latitude])
def inverted(self):
# docstring inherited
return LambertAxes.LambertTransform(
self._center_longitude,
self._center_latitude,
self._resolution)
def __init__(self, *args, center_longitude=0, center_latitude=0, **kwargs):
self._longitude_cap = np.pi / 2
self._center_longitude = center_longitude
self._center_latitude = center_latitude
super().__init__(*args, **kwargs)
self.set_aspect('equal', adjustable='box', anchor='C')
self.clear()
def clear(self):
# docstring inherited
super().clear()
self.yaxis.set_major_formatter(NullFormatter())
def _get_core_transform(self, resolution):
return self.LambertTransform(
self._center_longitude,
self._center_latitude,
resolution)
def _get_affine_transform(self):
return Affine2D() \
.scale(0.25) \
.translate(0.5, 0.5)

View file

@ -0,0 +1,112 @@
from matplotlib.axes import Axes
from matplotlib.ticker import Formatter
from matplotlib.transforms import Transform
from typing import Any, Literal
class GeoAxes(Axes):
class ThetaFormatter(Formatter):
def __init__(self, round_to: float = ...) -> None: ...
def __call__(self, x: float, pos: Any | None = ...): ...
RESOLUTION: float
def get_xaxis_transform(
self, which: Literal["tick1", "tick2", "grid"] = ...
) -> Transform: ...
def get_xaxis_text1_transform(
self, pad: float
) -> tuple[
Transform,
Literal["center", "top", "bottom", "baseline", "center_baseline"],
Literal["center", "left", "right"],
]: ...
def get_xaxis_text2_transform(
self, pad: float
) -> tuple[
Transform,
Literal["center", "top", "bottom", "baseline", "center_baseline"],
Literal["center", "left", "right"],
]: ...
def get_yaxis_transform(
self, which: Literal["tick1", "tick2", "grid"] = ...
) -> Transform: ...
def get_yaxis_text1_transform(
self, pad: float
) -> tuple[
Transform,
Literal["center", "top", "bottom", "baseline", "center_baseline"],
Literal["center", "left", "right"],
]: ...
def get_yaxis_text2_transform(
self, pad: float
) -> tuple[
Transform,
Literal["center", "top", "bottom", "baseline", "center_baseline"],
Literal["center", "left", "right"],
]: ...
def set_xlim(self, *args, **kwargs) -> tuple[float, float]: ...
def set_ylim(self, *args, **kwargs) -> tuple[float, float]: ...
def format_coord(self, lon: float, lat: float) -> str: ...
def set_longitude_grid(self, degrees: float) -> None: ...
def set_latitude_grid(self, degrees: float) -> None: ...
def set_longitude_grid_ends(self, degrees: float) -> None: ...
def get_data_ratio(self) -> float: ...
def can_zoom(self) -> bool: ...
def can_pan(self) -> bool: ...
def start_pan(self, x, y, button) -> None: ...
def end_pan(self) -> None: ...
def drag_pan(self, button, key, x, y) -> None: ...
class _GeoTransform(Transform):
input_dims: int
output_dims: int
def __init__(self, resolution: int) -> None: ...
class AitoffAxes(GeoAxes):
name: str
class AitoffTransform(_GeoTransform):
def inverted(self) -> AitoffAxes.InvertedAitoffTransform: ...
class InvertedAitoffTransform(_GeoTransform):
def inverted(self) -> AitoffAxes.AitoffTransform: ...
class HammerAxes(GeoAxes):
name: str
class HammerTransform(_GeoTransform):
def inverted(self) -> HammerAxes.InvertedHammerTransform: ...
class InvertedHammerTransform(_GeoTransform):
def inverted(self) -> HammerAxes.HammerTransform: ...
class MollweideAxes(GeoAxes):
name: str
class MollweideTransform(_GeoTransform):
def inverted(self) -> MollweideAxes.InvertedMollweideTransform: ...
class InvertedMollweideTransform(_GeoTransform):
def inverted(self) -> MollweideAxes.MollweideTransform: ...
class LambertAxes(GeoAxes):
name: str
class LambertTransform(_GeoTransform):
def __init__(
self, center_longitude: float, center_latitude: float, resolution: int
) -> None: ...
def inverted(self) -> LambertAxes.InvertedLambertTransform: ...
class InvertedLambertTransform(_GeoTransform):
def __init__(
self, center_longitude: float, center_latitude: float, resolution: int
) -> None: ...
def inverted(self) -> LambertAxes.LambertTransform: ...
def __init__(
self,
*args,
center_longitude: float = ...,
center_latitude: float = ...,
**kwargs
) -> None: ...

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,197 @@
import matplotlib.axis as maxis
import matplotlib.ticker as mticker
import matplotlib.transforms as mtransforms
from matplotlib.axes import Axes
from matplotlib.lines import Line2D
from matplotlib.text import Text
import numpy as np
from numpy.typing import ArrayLike
from collections.abc import Sequence
from typing import Any, ClassVar, Literal, overload
class PolarTransform(mtransforms.Transform):
input_dims: int
output_dims: int
def __init__(
self,
axis: PolarAxes | None = ...,
use_rmin: bool = ...,
*,
apply_theta_transforms: bool = ...,
scale_transform: mtransforms.Transform | None = ...,
) -> None: ...
def inverted(self) -> InvertedPolarTransform: ...
class PolarAffine(mtransforms.Affine2DBase):
def __init__(
self, scale_transform: mtransforms.Transform, limits: mtransforms.BboxBase
) -> None: ...
class InvertedPolarTransform(mtransforms.Transform):
input_dims: int
output_dims: int
def __init__(
self,
axis: PolarAxes | None = ...,
use_rmin: bool = ...,
*,
apply_theta_transforms: bool = ...,
) -> None: ...
def inverted(self) -> PolarTransform: ...
class ThetaFormatter(mticker.Formatter): ...
class _AxisWrapper:
def __init__(self, axis: maxis.Axis) -> None: ...
def get_view_interval(self) -> np.ndarray: ...
def set_view_interval(self, vmin: float, vmax: float) -> None: ...
def get_minpos(self) -> float: ...
def get_data_interval(self) -> np.ndarray: ...
def set_data_interval(self, vmin: float, vmax: float) -> None: ...
def get_tick_space(self) -> int: ...
class ThetaLocator(mticker.Locator):
base: mticker.Locator
axis: _AxisWrapper | None
def __init__(self, base: mticker.Locator) -> None: ...
class ThetaTick(maxis.XTick):
def __init__(self, axes: PolarAxes, *args, **kwargs) -> None: ...
class ThetaAxis(maxis.XAxis):
axis_name: str
class RadialLocator(mticker.Locator):
base: mticker.Locator
def __init__(self, base, axes: PolarAxes | None = ...) -> None: ...
class RadialTick(maxis.YTick): ...
class RadialAxis(maxis.YAxis):
axis_name: str
class _WedgeBbox(mtransforms.Bbox):
def __init__(
self,
center: tuple[float, float],
viewLim: mtransforms.Bbox,
originLim: mtransforms.Bbox,
**kwargs,
) -> None: ...
class PolarAxes(Axes):
PolarTransform: ClassVar[type] = PolarTransform
PolarAffine: ClassVar[type] = PolarAffine
InvertedPolarTransform: ClassVar[type] = InvertedPolarTransform
ThetaFormatter: ClassVar[type] = ThetaFormatter
RadialLocator: ClassVar[type] = RadialLocator
ThetaLocator: ClassVar[type] = ThetaLocator
name: str
use_sticky_edges: bool
def __init__(
self,
*args,
theta_offset: float = ...,
theta_direction: float = ...,
rlabel_position: float = ...,
**kwargs,
) -> None: ...
def get_xaxis_transform(
self, which: Literal["tick1", "tick2", "grid"] = ...
) -> mtransforms.Transform: ...
def get_xaxis_text1_transform(
self, pad: float
) -> tuple[
mtransforms.Transform,
Literal["center", "top", "bottom", "baseline", "center_baseline"],
Literal["center", "left", "right"],
]: ...
def get_xaxis_text2_transform(
self, pad: float
) -> tuple[
mtransforms.Transform,
Literal["center", "top", "bottom", "baseline", "center_baseline"],
Literal["center", "left", "right"],
]: ...
def get_yaxis_transform(
self, which: Literal["tick1", "tick2", "grid"] = ...
) -> mtransforms.Transform: ...
def get_yaxis_text1_transform(
self, pad: float
) -> tuple[
mtransforms.Transform,
Literal["center", "top", "bottom", "baseline", "center_baseline"],
Literal["center", "left", "right"],
]: ...
def get_yaxis_text2_transform(
self, pad: float
) -> tuple[
mtransforms.Transform,
Literal["center", "top", "bottom", "baseline", "center_baseline"],
Literal["center", "left", "right"],
]: ...
def set_thetamax(self, thetamax: float) -> None: ...
def get_thetamax(self) -> float: ...
def set_thetamin(self, thetamin: float) -> None: ...
def get_thetamin(self) -> float: ...
@overload
def set_thetalim(self, minval: float, maxval: float, /) -> tuple[float, float]: ...
@overload
def set_thetalim(self, *, thetamin: float, thetamax: float) -> tuple[float, float]: ...
def set_theta_offset(self, offset: float) -> None: ...
def get_theta_offset(self) -> float: ...
def set_theta_zero_location(
self,
loc: Literal["N", "NW", "W", "SW", "S", "SE", "E", "NE"],
offset: float = ...,
) -> None: ...
def set_theta_direction(
self,
direction: Literal[-1, 1, "clockwise", "counterclockwise", "anticlockwise"],
) -> None: ...
def get_theta_direction(self) -> Literal[-1, 1]: ...
def set_rmax(self, rmax: float) -> None: ...
def get_rmax(self) -> float: ...
def set_rmin(self, rmin: float) -> None: ...
def get_rmin(self) -> float: ...
def set_rorigin(self, rorigin: float | None) -> None: ...
def get_rorigin(self) -> float: ...
def get_rsign(self) -> float: ...
def set_rlim(
self,
bottom: float | tuple[float, float] | None = ...,
top: float | None = ...,
*,
emit: bool = ...,
auto: bool = ...,
**kwargs,
) -> tuple[float, float]: ...
def get_rlabel_position(self) -> float: ...
def set_rlabel_position(self, value: float) -> None: ...
def set_rscale(self, *args, **kwargs) -> None: ...
def set_rticks(self, *args, **kwargs) -> None: ...
def set_thetagrids(
self,
angles: ArrayLike,
labels: Sequence[str | Text] | None = ...,
fmt: str | None = ...,
**kwargs,
) -> tuple[list[Line2D], list[Text]]: ...
def set_rgrids(
self,
radii: ArrayLike,
labels: Sequence[str | Text] | None = ...,
angle: float | None = ...,
fmt: str | None = ...,
**kwargs,
) -> tuple[list[Line2D], list[Text]]: ...
def format_coord(self, theta: float, r: float) -> str: ...
def get_data_ratio(self) -> float: ...
def can_zoom(self) -> bool: ...
def can_pan(self) -> bool: ...
def start_pan(self, x: float, y: float, button: int) -> None: ...
def end_pan(self) -> None: ...
def drag_pan(self, button: Any, key: Any, x: float, y: float) -> None: ...