Matplotlib supports the addition of custom procedures that transform the data before it is displayed.
There is an important distinction between two kinds of transformations. Separable transformations, working on a single dimension, are called “scales”, and non-separable transformations, that handle data in two or more dimensions at a time, are called “projections”.
From the user’s perspective, the scale of a plot can be set with
set_xscale()
and
set_yscale()
. Projections can be chosen
using the projection
keyword argument to the
plot()
or subplot()
functions, e.g.:
plot(x, y, projection="custom")
This document is intended for developers and advanced users who need to create new scales and projections for matplotlib. The necessary code for scales and projections can be included anywhere: directly within a plot script, in third-party code, or in the matplotlib source tree itself.
Adding a new scale consists of defining a subclass of
matplotlib.scale.ScaleBase
, that includes 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.
- A function to limit the range of the axis to acceptable values (
limit_range_for_scale()
). A log scale, for instance, would prevent the range from including values less than or equal to zero.- Locators (major and minor) that determine where to place ticks in the plot, and optionally, how to adjust the limits of the plot to some “good” values. Unlike
limit_range_for_scale()
, which is always enforced, the range setting here is only used when automatically setting the range of the plot.- Formatters (major and minor) that specify how the tick labels should be drawn.
Once the class is defined, it must be registered with matplotlib so that the user can select it.
A full-fledged and heavily annotated example is in
examples/api/custom_scale_example.py
. There are also some classes
in matplotlib.scale
that may be used as starting points.
Adding a new projection consists of defining a projection axes which
subclasses matplotlib.axes.Axes
and includes 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
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 withmatplotlib.projections.register_projection()
and subsequently simply invoked by name:plt.axes(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:plt.axes(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
examples/api/custom_projection_example.py
. The polar plot
functionality in matplotlib.projections.polar
may also be of
interest.
matplotlib.scale.
LinearScale
(axis, **kwargs)¶Bases: matplotlib.scale.ScaleBase
The default linear scale.
get_transform
()¶The transform for linear scaling is just the
IdentityTransform
.
set_default_locators_and_formatters
(axis)¶Set the locators and formatters to reasonable defaults for linear scaling.
matplotlib.scale.
LogScale
(axis, **kwargs)¶Bases: matplotlib.scale.ScaleBase
A standard logarithmic scale. Care is taken so non-positive values are not plotted.
For computational efficiency (to push as much as possible to Numpy C code in the common cases), this scale provides different transforms depending on the base of the logarithm:
- base 10 (
Log10Transform
)- base 2 (
Log2Transform
)- base e (
NaturalLogTransform
)- arbitrary base (
LogTransform
)
Where to place the subticks between each major tick.
Should be a sequence of integers. For example, in a log10
scale: [2, 3, 4, 5, 6, 7, 8, 9]
will place 8 logarithmically spaced minor ticks between each major tick.
limit_range_for_scale
(vmin, vmax, minpos)¶Limit the domain to positive values.
set_default_locators_and_formatters
(axis)¶Set the locators and formatters to specialized versions for log scaling.
matplotlib.scale.
LogitScale
(axis, nonpos='mask')¶Bases: matplotlib.scale.ScaleBase
Logit scale for data between zero and one, both excluded.
This scale is similar to a log scale close to zero and to one, and almost linear around 0.5. It maps the interval ]0, 1[ onto ]-infty, +infty[.
get_transform
()¶Return a LogitTransform
instance.
limit_range_for_scale
(vmin, vmax, minpos)¶Limit the domain to values between 0 and 1 (excluded).
matplotlib.scale.
ScaleBase
¶Bases: object
The base class for all scales.
Scales are separable transformations, working on a single dimension.
Any subclasses will want to override:
limit_range_for_scale
(vmin, vmax, minpos)¶Returns the range vmin, vmax, possibly limited to the domain supported by this scale.
matplotlib.scale.
SymmetricalLogScale
(axis, **kwargs)¶Bases: matplotlib.scale.ScaleBase
The symmetrical logarithmic scale is logarithmic in both the positive and negative directions from the origin.
Since the values close to zero tend toward infinity, there is a need to have a range around zero that is linear. The parameter linthresh allows the user to specify the size of this range (-linthresh, linthresh).
Where to place the subticks between each major tick.
Should be a sequence of integers. For example, in a log10
scale: [2, 3, 4, 5, 6, 7, 8, 9]
will place 8 logarithmically spaced minor ticks between each major tick.
get_transform
()¶Return a SymmetricalLogTransform
instance.
set_default_locators_and_formatters
(axis)¶Set the locators and formatters to specialized versions for symmetrical log scaling.
matplotlib.scale.
get_scale_docs
()¶Helper function for generating docstrings related to scales.
matplotlib.scale.
register_scale
(scale_class)¶Register a new kind of scale.
scale_class must be a subclass of ScaleBase
.
matplotlib.scale.
scale_factory
(scale, axis, **kwargs)¶Return a scale class by name.
ACCEPTS: [ linear | log | logit | symlog ]
matplotlib.projections.
ProjectionRegistry
¶Bases: object
Manages the set of projections available to the system.
get_projection_class
(name)¶Get a projection class from its name.
get_projection_names
()¶Get a list of the names of all projections currently registered.
register
(*projections)¶Register a new set of projection(s).
matplotlib.projections.
get_projection_class
(projection=None)¶Get a projection class from its name.
If projection is None, a standard rectilinear projection is returned.
matplotlib.projections.
get_projection_names
()¶Get a list of acceptable projection names.
matplotlib.projections.
process_projection_requirements
(figure, *args, **kwargs)¶Handle the args/kwargs to for add_axes/add_subplot/gca, returning:
(axes_proj_class, proj_class_kwargs, proj_stack_key)
Which can be used for new axes initialization/identification.
Note
kwargs is modified in place.
matplotlib.projections.polar.
InvertedPolarTransform
(axis=None, use_rmin=True)¶Bases: matplotlib.transforms.Transform
The inverse of the polar transform, mapping Cartesian coordinate space x and y back to theta and r.
inverted
()¶Return the corresponding inverse transformation.
The return value of this method should be treated as temporary. An update to self does not cause a corresponding update to its inverted copy.
x === self.inverted().transform(self.transform(x))
transform_non_affine
(xy)¶Performs only the non-affine part of the transformation.
transform(values)
is always equivalent to
transform_affine(transform_non_affine(values))
.
In non-affine transformations, this is generally equivalent to
transform(values)
. In affine transformations, this is
always a no-op.
Accepts a numpy array of shape (N x input_dims
) and
returns a numpy array of shape (N x output_dims
).
Alternatively, accepts a numpy array of length input_dims
and returns a numpy array of length output_dims
.
matplotlib.projections.polar.
PolarAffine
(scale_transform, limits)¶Bases: matplotlib.transforms.Affine2DBase
The affine part of the polar projection. Scales the output so that maximum radius rests on the edge of the axes circle.
limits is the view limit of the data. The only part of its bounds that is used is ymax (for the radius maximum). The theta range is always fixed to (0, 2pi).
get_matrix
()¶Get the Affine transformation array for the affine part of this transform.
matplotlib.projections.polar.
PolarAxes
(*args, **kwargs)¶Bases: matplotlib.axes._axes.Axes
A polar graph projection, where the input dimensions are theta, r.
Theta starts pointing east and goes anti-clockwise.
InvertedPolarTransform
(axis=None, use_rmin=True)¶Bases: matplotlib.transforms.Transform
The inverse of the polar transform, mapping Cartesian coordinate space x and y back to theta and r.
inverted
()¶Return the corresponding inverse transformation.
The return value of this method should be treated as temporary. An update to self does not cause a corresponding update to its inverted copy.
x === self.inverted().transform(self.transform(x))
transform_non_affine
(xy)¶Performs only the non-affine part of the transformation.
transform(values)
is always equivalent to
transform_affine(transform_non_affine(values))
.
In non-affine transformations, this is generally equivalent to
transform(values)
. In affine transformations, this is
always a no-op.
Accepts a numpy array of shape (N x input_dims
) and
returns a numpy array of shape (N x output_dims
).
Alternatively, accepts a numpy array of length input_dims
and returns a numpy array of length output_dims
.
PolarAxes.
PolarAffine
(scale_transform, limits)¶Bases: matplotlib.transforms.Affine2DBase
The affine part of the polar projection. Scales the output so that maximum radius rests on the edge of the axes circle.
limits is the view limit of the data. The only part of its bounds that is used is ymax (for the radius maximum). The theta range is always fixed to (0, 2pi).
get_matrix
()¶Get the Affine transformation array for the affine part of this transform.
PolarAxes.
PolarTransform
(axis=None, use_rmin=True)¶Bases: matplotlib.transforms.Transform
The base polar transform. This handles projection theta and r into Cartesian coordinate space x and y, but does not perform the ultimate affine transformation into the correct position.
inverted
()¶Return the corresponding inverse transformation.
The return value of this method should be treated as temporary. An update to self does not cause a corresponding update to its inverted copy.
x === self.inverted().transform(self.transform(x))
transform_non_affine
(tr)¶Performs only the non-affine part of the transformation.
transform(values)
is always equivalent to
transform_affine(transform_non_affine(values))
.
In non-affine transformations, this is generally equivalent to
transform(values)
. In affine transformations, this is
always a no-op.
Accepts a numpy array of shape (N x input_dims
) and
returns a numpy array of shape (N x output_dims
).
Alternatively, accepts a numpy array of length input_dims
and returns a numpy array of length output_dims
.
PolarAxes.
RadialLocator
(base)¶Bases: matplotlib.ticker.Locator
Used to locate radius ticks.
Ensures that all ticks are strictly positive. For all other
tasks, it delegates to the base
Locator
(which may be different
depending on the scale of the r-axis.
PolarAxes.
ThetaFormatter
¶Bases: matplotlib.ticker.Formatter
Used to format the theta tick labels. Converts the native unit of radians into degrees and adds a degree symbol.
PolarAxes.
can_pan
()¶Return True if this axes supports the pan/zoom button functionality.
For polar axes, this is slightly misleading. Both panning and zooming are performed by the same button. Panning is performed in azimuth while zooming is done along the radial.
PolarAxes.
can_zoom
()¶Return True if this axes supports the zoom box button functionality.
Polar axes do not support zoom boxes.
PolarAxes.
format_coord
(theta, r)¶Return a format string formatting the coordinate using Unicode characters.
PolarAxes.
get_data_ratio
()¶Return the aspect ratio of the data itself. For a polar plot, this should always be 1.0
PolarAxes.
get_rlabel_position
()¶Returns: | float
|
---|
PolarAxes.
get_theta_direction
()¶Get the direction in which theta increases.
PolarAxes.
get_theta_offset
()¶Get the offset for the location of 0 in radians.
PolarAxes.
set_rgrids
(radii, labels=None, angle=None, fmt=None, **kwargs)¶Set the radial locations and labels of the r grids.
The labels will appear at radial distances radii at the given angle in degrees.
labels, if not None, is a len(radii)
list of strings of the
labels to use at each radius.
If labels is None, the built-in formatter will be used.
Return value is a list of tuples (line, label), where
line is Line2D
instances and the
label is Text
instances.
kwargs are optional text properties for the labels:
Property Description agg_filter
unknown alpha
float (0.0 transparent through 1.0 opaque) animated
[True | False] axes
an Axes
instancebackgroundcolor
any matplotlib color bbox
FancyBboxPatch prop dict bottom_margin
unknown clip_box
a matplotlib.transforms.Bbox
instanceclip_on
[True | False] clip_path
[ ( Path
,Transform
) |Patch
| None ]color
any matplotlib color contains
a callable function family
or fontfamily or fontname or name[FONTNAME | ‘serif’ | ‘sans-serif’ | ‘cursive’ | ‘fantasy’ | ‘monospace’ ] figure
a matplotlib.figure.Figure
instancefontproperties
or font_propertiesa matplotlib.font_manager.FontProperties
instancegid
an id string horizontalalignment
or ha[ ‘center’ | ‘right’ | ‘left’ ] label
string or anything printable with ‘%s’ conversion. left_margin
unknown linespacing
float (multiple of font size) margins
unknown multialignment
[‘left’ | ‘right’ | ‘center’ ] path_effects
unknown picker
[None|float|boolean|callable] position
(x,y) rasterized
[True | False | None] right_margin
unknown rotation
[ angle in degrees | ‘vertical’ | ‘horizontal’ ] rotation_mode
unknown size
or fontsize[size in points | ‘xx-small’ | ‘x-small’ | ‘small’ | ‘medium’ | ‘large’ | ‘x-large’ | ‘xx-large’ ] sketch_params
unknown snap
unknown stretch
or fontstretch[a numeric value in range 0-1000 | ‘ultra-condensed’ | ‘extra-condensed’ | ‘condensed’ | ‘semi-condensed’ | ‘normal’ | ‘semi-expanded’ | ‘expanded’ | ‘extra-expanded’ | ‘ultra-expanded’ ] style
or fontstyle[ ‘normal’ | ‘italic’ | ‘oblique’] text
string or anything printable with ‘%s’ conversion. top_margin
unknown transform
Transform
instanceurl
a url string usetex
unknown variant
or fontvariant[ ‘normal’ | ‘small-caps’ ] verticalalignment
or ma or va[ ‘center’ | ‘top’ | ‘bottom’ | ‘baseline’ ] visible
[True | False] weight
or fontweight[a numeric value in range 0-1000 | ‘ultralight’ | ‘light’ | ‘normal’ | ‘regular’ | ‘book’ | ‘medium’ | ‘roman’ | ‘semibold’ | ‘demibold’ | ‘demi’ | ‘bold’ | ‘heavy’ | ‘extra bold’ | ‘black’ ] wrap
unknown x
float y
float zorder
any number
ACCEPTS: sequence of floats
PolarAxes.
set_rlabel_position
(value)¶Updates the theta position of the radius labels.
Parameters: | value : number
|
---|
PolarAxes.
set_theta_direction
(direction)¶Set the direction in which theta increases.
PolarAxes.
set_theta_offset
(offset)¶Set the offset for the location of 0 in radians.
PolarAxes.
set_theta_zero_location
(loc)¶Sets the location of theta’s zero. (Calls set_theta_offset with the correct value in radians under the hood.)
May be one of “N”, “NW”, “W”, “SW”, “S”, “SE”, “E”, or “NE”.
PolarAxes.
set_thetagrids
(angles, labels=None, frac=None, fmt=None, **kwargs)¶Set the angles at which to place the theta grids (these gridlines are equal along the theta dimension). angles is in degrees.
labels, if not None, is a len(angles)
list of strings of
the labels to use at each angle.
If labels is None, the labels will be fmt % angle
frac is the fraction of the polar axes radius at which to place the label (1 is the edge). e.g., 1.05 is outside the axes and 0.95 is inside the axes.
Return value is a list of tuples (line, label), where
line is Line2D
instances and the
label is Text
instances.
kwargs are optional text properties for the labels:
Property Description agg_filter
unknown alpha
float (0.0 transparent through 1.0 opaque) animated
[True | False] axes
an Axes
instancebackgroundcolor
any matplotlib color bbox
FancyBboxPatch prop dict bottom_margin
unknown clip_box
a matplotlib.transforms.Bbox
instanceclip_on
[True | False] clip_path
[ ( Path
,Transform
) |Patch
| None ]color
any matplotlib color contains
a callable function family
or fontfamily or fontname or name[FONTNAME | ‘serif’ | ‘sans-serif’ | ‘cursive’ | ‘fantasy’ | ‘monospace’ ] figure
a matplotlib.figure.Figure
instancefontproperties
or font_propertiesa matplotlib.font_manager.FontProperties
instancegid
an id string horizontalalignment
or ha[ ‘center’ | ‘right’ | ‘left’ ] label
string or anything printable with ‘%s’ conversion. left_margin
unknown linespacing
float (multiple of font size) margins
unknown multialignment
[‘left’ | ‘right’ | ‘center’ ] path_effects
unknown picker
[None|float|boolean|callable] position
(x,y) rasterized
[True | False | None] right_margin
unknown rotation
[ angle in degrees | ‘vertical’ | ‘horizontal’ ] rotation_mode
unknown size
or fontsize[size in points | ‘xx-small’ | ‘x-small’ | ‘small’ | ‘medium’ | ‘large’ | ‘x-large’ | ‘xx-large’ ] sketch_params
unknown snap
unknown stretch
or fontstretch[a numeric value in range 0-1000 | ‘ultra-condensed’ | ‘extra-condensed’ | ‘condensed’ | ‘semi-condensed’ | ‘normal’ | ‘semi-expanded’ | ‘expanded’ | ‘extra-expanded’ | ‘ultra-expanded’ ] style
or fontstyle[ ‘normal’ | ‘italic’ | ‘oblique’] text
string or anything printable with ‘%s’ conversion. top_margin
unknown transform
Transform
instanceurl
a url string usetex
unknown variant
or fontvariant[ ‘normal’ | ‘small-caps’ ] verticalalignment
or ma or va[ ‘center’ | ‘top’ | ‘bottom’ | ‘baseline’ ] visible
[True | False] weight
or fontweight[a numeric value in range 0-1000 | ‘ultralight’ | ‘light’ | ‘normal’ | ‘regular’ | ‘book’ | ‘medium’ | ‘roman’ | ‘semibold’ | ‘demibold’ | ‘demi’ | ‘bold’ | ‘heavy’ | ‘extra bold’ | ‘black’ ] wrap
unknown x
float y
float zorder
any number
ACCEPTS: sequence of floats
matplotlib.projections.polar.
PolarTransform
(axis=None, use_rmin=True)¶Bases: matplotlib.transforms.Transform
The base polar transform. This handles projection theta and r into Cartesian coordinate space x and y, but does not perform the ultimate affine transformation into the correct position.
inverted
()¶Return the corresponding inverse transformation.
The return value of this method should be treated as temporary. An update to self does not cause a corresponding update to its inverted copy.
x === self.inverted().transform(self.transform(x))
transform_non_affine
(tr)¶Performs only the non-affine part of the transformation.
transform(values)
is always equivalent to
transform_affine(transform_non_affine(values))
.
In non-affine transformations, this is generally equivalent to
transform(values)
. In affine transformations, this is
always a no-op.
Accepts a numpy array of shape (N x input_dims
) and
returns a numpy array of shape (N x output_dims
).
Alternatively, accepts a numpy array of length input_dims
and returns a numpy array of length output_dims
.
matplotlib.projections.polar.
RadialLocator
(base)¶Bases: matplotlib.ticker.Locator
Used to locate radius ticks.
Ensures that all ticks are strictly positive. For all other
tasks, it delegates to the base
Locator
(which may be different
depending on the scale of the r-axis.
matplotlib.projections.polar.
ThetaFormatter
¶Bases: matplotlib.ticker.Formatter
Used to format the theta tick labels. Converts the native unit of radians into degrees and adds a degree symbol.