mirror of
https://github.com/Estom/notes.git
synced 2026-04-04 03:17:44 +08:00
matplotlib & pandas
This commit is contained in:
830
Python/matplotlab/intermediate/artists.md
Normal file
830
Python/matplotlab/intermediate/artists.md
Normal file
@@ -0,0 +1,830 @@
|
||||
---
|
||||
sidebarDepth: 3
|
||||
sidebar: auto
|
||||
---
|
||||
|
||||
# Artist tutorial
|
||||
|
||||
Using Artist objects to render on the canvas.
|
||||
|
||||
There are three layers to the matplotlib API.
|
||||
|
||||
- the ``matplotlib.backend_bases.FigureCanvas`` is the area onto which
|
||||
the figure is drawn
|
||||
- the ``matplotlib.backend_bases.Renderer`` is
|
||||
the object which knows how to draw on the
|
||||
``FigureCanvas``
|
||||
- and the [``matplotlib.artist.Artist``](https://matplotlib.orgapi/artist_api.html#matplotlib.artist.Artist) is the object that knows how to use
|
||||
a renderer to paint onto the canvas.
|
||||
|
||||
The ``FigureCanvas`` and
|
||||
``Renderer`` handle all the details of
|
||||
talking to user interface toolkits like [wxPython](https://www.wxpython.org) or drawing languages like PostScript®, and
|
||||
the ``Artist`` handles all the high level constructs like representing
|
||||
and laying out the figure, text, and lines. The typical user will
|
||||
spend 95% of their time working with the ``Artists``.
|
||||
|
||||
There are two types of ``Artists``: primitives and containers. The primitives
|
||||
represent the standard graphical objects we want to paint onto our canvas:
|
||||
[``Line2D``](https://matplotlib.orgapi/_as_gen/matplotlib.lines.Line2D.html#matplotlib.lines.Line2D), [``Rectangle``](https://matplotlib.orgapi/_as_gen/matplotlib.patches.Rectangle.html#matplotlib.patches.Rectangle),
|
||||
[``Text``](https://matplotlib.orgapi/text_api.html#matplotlib.text.Text), [``AxesImage``](https://matplotlib.orgapi/image_api.html#matplotlib.image.AxesImage), etc., and
|
||||
the containers are places to put them ([``Axis``](https://matplotlib.orgapi/axis_api.html#matplotlib.axis.Axis),
|
||||
[``Axes``](https://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes) and [``Figure``](https://matplotlib.orgapi/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure)). The
|
||||
standard use is to create a [``Figure``](https://matplotlib.orgapi/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure) instance, use
|
||||
the ``Figure`` to create one or more [``Axes``](https://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes) or
|
||||
``Subplot`` instances, and use the ``Axes`` instance
|
||||
helper methods to create the primitives. In the example below, we create a
|
||||
``Figure`` instance using [``matplotlib.pyplot.figure()``](https://matplotlib.orgapi/_as_gen/matplotlib.pyplot.figure.html#matplotlib.pyplot.figure), which is a
|
||||
convenience method for instantiating ``Figure`` instances and connecting them
|
||||
with your user interface or drawing toolkit ``FigureCanvas``. As we will
|
||||
discuss below, this is not necessary -- you can work directly with PostScript,
|
||||
PDF Gtk+, or wxPython ``FigureCanvas`` instances, instantiate your ``Figures``
|
||||
directly and connect them yourselves -- but since we are focusing here on the
|
||||
``Artist`` API we'll let [``pyplot``](https://matplotlib.orgapi/_as_gen/matplotlib.pyplot.html#module-matplotlib.pyplot) handle some of those details
|
||||
for us:
|
||||
|
||||
``` python
|
||||
import matplotlib.pyplot as plt
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(2, 1, 1) # two rows, one column, first plot
|
||||
```
|
||||
|
||||
The [``Axes``](https://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes) is probably the most important
|
||||
class in the matplotlib API, and the one you will be working with most
|
||||
of the time. This is because the ``Axes`` is the plotting area into
|
||||
which most of the objects go, and the ``Axes`` has many special helper
|
||||
methods ([``plot()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.plot.html#matplotlib.axes.Axes.plot),
|
||||
[``text()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.text.html#matplotlib.axes.Axes.text),
|
||||
[``hist()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.hist.html#matplotlib.axes.Axes.hist),
|
||||
[``imshow()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.imshow.html#matplotlib.axes.Axes.imshow)) to create the most common
|
||||
graphics primitives ([``Line2D``](https://matplotlib.orgapi/_as_gen/matplotlib.lines.Line2D.html#matplotlib.lines.Line2D),
|
||||
[``Text``](https://matplotlib.orgapi/text_api.html#matplotlib.text.Text),
|
||||
[``Rectangle``](https://matplotlib.orgapi/_as_gen/matplotlib.patches.Rectangle.html#matplotlib.patches.Rectangle),
|
||||
``Image``, respectively). These helper methods
|
||||
will take your data (e.g., ``numpy`` arrays and strings) and create
|
||||
primitive ``Artist`` instances as needed (e.g., ``Line2D``), add them to
|
||||
the relevant containers, and draw them when requested. Most of you
|
||||
are probably familiar with the ``Subplot``,
|
||||
which is just a special case of an ``Axes`` that lives on a regular
|
||||
rows by columns grid of ``Subplot`` instances. If you want to create
|
||||
an ``Axes`` at an arbitrary location, simply use the
|
||||
[``add_axes()``](https://matplotlib.orgapi/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure.add_axes) method which takes a list
|
||||
of ``[left, bottom, width, height]`` values in 0-1 relative figure
|
||||
coordinates:
|
||||
|
||||
``` python
|
||||
fig2 = plt.figure()
|
||||
ax2 = fig2.add_axes([0.15, 0.1, 0.7, 0.3])
|
||||
```
|
||||
|
||||
Continuing with our example:
|
||||
|
||||
``` python
|
||||
import numpy as np
|
||||
t = np.arange(0.0, 1.0, 0.01)
|
||||
s = np.sin(2*np.pi*t)
|
||||
line, = ax.plot(t, s, color='blue', lw=2)
|
||||
```
|
||||
|
||||
In this example, ``ax`` is the ``Axes`` instance created by the
|
||||
``fig.add_subplot`` call above (remember ``Subplot`` is just a
|
||||
subclass of ``Axes``) and when you call ``ax.plot``, it creates a
|
||||
``Line2D`` instance and adds it to the ``Axes.lines`` list. In the interactive [ipython](http://ipython.org/) session below, you can see that the
|
||||
``Axes.lines`` list is length one and contains the same line that was
|
||||
returned by the ``line, = ax.plot...`` call:
|
||||
|
||||
``` python
|
||||
In [101]: ax.lines[0]
|
||||
Out[101]: <matplotlib.lines.Line2D instance at 0x19a95710>
|
||||
|
||||
In [102]: line
|
||||
Out[102]: <matplotlib.lines.Line2D instance at 0x19a95710>
|
||||
```
|
||||
|
||||
If you make subsequent calls to ``ax.plot`` (and the hold state is "on"
|
||||
which is the default) then additional lines will be added to the list.
|
||||
You can remove lines later simply by calling the list methods; either
|
||||
of these will work:
|
||||
|
||||
``` python
|
||||
del ax.lines[0]
|
||||
ax.lines.remove(line) # one or the other, not both!
|
||||
```
|
||||
|
||||
The Axes also has helper methods to configure and decorate the x-axis
|
||||
and y-axis tick, tick labels and axis labels:
|
||||
|
||||
``` python
|
||||
xtext = ax.set_xlabel('my xdata') # returns a Text instance
|
||||
ytext = ax.set_ylabel('my ydata')
|
||||
```
|
||||
|
||||
When you call [``ax.set_xlabel``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.set_xlabel.html#matplotlib.axes.Axes.set_xlabel),
|
||||
it passes the information on the [``Text``](https://matplotlib.orgapi/text_api.html#matplotlib.text.Text)
|
||||
instance of the [``XAxis``](https://matplotlib.orgapi/axis_api.html#matplotlib.axis.XAxis). Each ``Axes``
|
||||
instance contains an [``XAxis``](https://matplotlib.orgapi/axis_api.html#matplotlib.axis.XAxis) and a
|
||||
[``YAxis``](https://matplotlib.orgapi/axis_api.html#matplotlib.axis.YAxis) instance, which handle the layout and
|
||||
drawing of the ticks, tick labels and axis labels.
|
||||
|
||||
Try creating the figure below.
|
||||
|
||||
``` python
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
fig = plt.figure()
|
||||
fig.subplots_adjust(top=0.8)
|
||||
ax1 = fig.add_subplot(211)
|
||||
ax1.set_ylabel('volts')
|
||||
ax1.set_title('a sine wave')
|
||||
|
||||
t = np.arange(0.0, 1.0, 0.01)
|
||||
s = np.sin(2*np.pi*t)
|
||||
line, = ax1.plot(t, s, color='blue', lw=2)
|
||||
|
||||
# Fixing random state for reproducibility
|
||||
np.random.seed(19680801)
|
||||
|
||||
ax2 = fig.add_axes([0.15, 0.1, 0.7, 0.3])
|
||||
n, bins, patches = ax2.hist(np.random.randn(1000), 50,
|
||||
facecolor='yellow', edgecolor='yellow')
|
||||
ax2.set_xlabel('time (s)')
|
||||
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Customizing your objects
|
||||
|
||||
Every element in the figure is represented by a matplotlib
|
||||
[``Artist``](https://matplotlib.orgapi/artist_api.html#matplotlib.artist.Artist), and each has an extensive list of
|
||||
properties to configure its appearance. The figure itself contains a
|
||||
[``Rectangle``](https://matplotlib.orgapi/_as_gen/matplotlib.patches.Rectangle.html#matplotlib.patches.Rectangle) exactly the size of the figure,
|
||||
which you can use to set the background color and transparency of the
|
||||
figures. Likewise, each [``Axes``](https://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes) bounding box
|
||||
(the standard white box with black edges in the typical matplotlib
|
||||
plot, has a ``Rectangle`` instance that determines the color,
|
||||
transparency, and other properties of the Axes. These instances are
|
||||
stored as member variables ``Figure.patch`` and ``Axes.patch`` ("Patch" is a name inherited from
|
||||
MATLAB, and is a 2D "patch" of color on the figure, e.g., rectangles,
|
||||
circles and polygons). Every matplotlib ``Artist`` has the following
|
||||
properties
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Property
|
||||
Description
|
||||
|
||||
|
||||
|
||||
alpha
|
||||
The transparency - a scalar from 0-1
|
||||
|
||||
animated
|
||||
A boolean that is used to facilitate animated drawing
|
||||
|
||||
axes
|
||||
The axes that the Artist lives in, possibly None
|
||||
|
||||
clip_box
|
||||
The bounding box that clips the Artist
|
||||
|
||||
clip_on
|
||||
Whether clipping is enabled
|
||||
|
||||
clip_path
|
||||
The path the artist is clipped to
|
||||
|
||||
contains
|
||||
A picking function to test whether the artist contains the pick point
|
||||
|
||||
figure
|
||||
The figure instance the artist lives in, possibly None
|
||||
|
||||
label
|
||||
A text label (e.g., for auto-labeling)
|
||||
|
||||
picker
|
||||
A python object that controls object picking
|
||||
|
||||
transform
|
||||
The transformation
|
||||
|
||||
visible
|
||||
A boolean whether the artist should be drawn
|
||||
|
||||
zorder
|
||||
A number which determines the drawing order
|
||||
|
||||
rasterized
|
||||
Boolean; Turns vectors into raster graphics (for compression & eps transparency)
|
||||
|
||||
|
||||
|
||||
|
||||
Each of the properties is accessed with an old-fashioned setter or
|
||||
getter (yes we know this irritates Pythonistas and we plan to support
|
||||
direct access via properties or traits but it hasn't been done yet).
|
||||
For example, to multiply the current alpha by a half:
|
||||
|
||||
``` python
|
||||
a = o.get_alpha()
|
||||
o.set_alpha(0.5*a)
|
||||
```
|
||||
|
||||
If you want to set a number of properties at once, you can also use
|
||||
the ``set`` method with keyword arguments. For example:
|
||||
|
||||
``` python
|
||||
o.set(alpha=0.5, zorder=2)
|
||||
```
|
||||
|
||||
If you are working interactively at the python shell, a handy way to
|
||||
inspect the ``Artist`` properties is to use the
|
||||
[``matplotlib.artist.getp()``](https://matplotlib.orgapi/_as_gen/matplotlib.artist.getp.html#matplotlib.artist.getp) function (simply
|
||||
``getp()`` in pyplot), which lists the properties
|
||||
and their values. This works for classes derived from ``Artist`` as
|
||||
well, e.g., ``Figure`` and ``Rectangle``. Here are the ``Figure`` rectangle
|
||||
properties mentioned above:
|
||||
|
||||
``` python
|
||||
In [149]: matplotlib.artist.getp(fig.patch)
|
||||
alpha = 1.0
|
||||
animated = False
|
||||
antialiased or aa = True
|
||||
axes = None
|
||||
clip_box = None
|
||||
clip_on = False
|
||||
clip_path = None
|
||||
contains = None
|
||||
edgecolor or ec = w
|
||||
facecolor or fc = 0.75
|
||||
figure = Figure(8.125x6.125)
|
||||
fill = 1
|
||||
hatch = None
|
||||
height = 1
|
||||
label =
|
||||
linewidth or lw = 1.0
|
||||
picker = None
|
||||
transform = <Affine object at 0x134cca84>
|
||||
verts = ((0, 0), (0, 1), (1, 1), (1, 0))
|
||||
visible = True
|
||||
width = 1
|
||||
window_extent = <Bbox object at 0x134acbcc>
|
||||
x = 0
|
||||
y = 0
|
||||
zorder = 1
|
||||
```
|
||||
|
||||
The docstrings for all of the classes also contain the ``Artist``
|
||||
properties, so you can consult the interactive "help" or the
|
||||
[matplotlib.artist](https://matplotlib.orgapi/artist_api.html#artist-api) for a listing of properties for a given object.
|
||||
|
||||
## Object containers
|
||||
|
||||
Now that we know how to inspect and set the properties of a given
|
||||
object we want to configure, we need to know how to get at that object.
|
||||
As mentioned in the introduction, there are two kinds of objects:
|
||||
primitives and containers. The primitives are usually the things you
|
||||
want to configure (the font of a [``Text``](https://matplotlib.orgapi/text_api.html#matplotlib.text.Text)
|
||||
instance, the width of a [``Line2D``](https://matplotlib.orgapi/_as_gen/matplotlib.lines.Line2D.html#matplotlib.lines.Line2D)) although
|
||||
the containers also have some properties as well -- for example the
|
||||
[``Axes``](https://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes) [``Artist``](https://matplotlib.orgapi/artist_api.html#matplotlib.artist.Artist) is a
|
||||
container that contains many of the primitives in your plot, but it
|
||||
also has properties like the ``xscale`` to control whether the xaxis
|
||||
is 'linear' or 'log'. In this section we'll review where the various
|
||||
container objects store the ``Artists`` that you want to get at.
|
||||
|
||||
### Figure container
|
||||
|
||||
The top level container ``Artist`` is the
|
||||
[``matplotlib.figure.Figure``](https://matplotlib.orgapi/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure), and it contains everything in the
|
||||
figure. The background of the figure is a
|
||||
[``Rectangle``](https://matplotlib.orgapi/_as_gen/matplotlib.patches.Rectangle.html#matplotlib.patches.Rectangle) which is stored in
|
||||
``Figure.patch``. As
|
||||
you add subplots ([``add_subplot()``](https://matplotlib.orgapi/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure.add_subplot)) and
|
||||
axes ([``add_axes()``](https://matplotlib.orgapi/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure.add_axes)) to the figure
|
||||
these will be appended to the [``Figure.axes``](https://matplotlib.orgapi/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure.axes). These are also returned by the
|
||||
methods that create them:
|
||||
|
||||
``` python
|
||||
In [156]: fig = plt.figure()
|
||||
|
||||
In [157]: ax1 = fig.add_subplot(211)
|
||||
|
||||
In [158]: ax2 = fig.add_axes([0.1, 0.1, 0.7, 0.3])
|
||||
|
||||
In [159]: ax1
|
||||
Out[159]: <matplotlib.axes.Subplot instance at 0xd54b26c>
|
||||
|
||||
In [160]: print(fig.axes)
|
||||
[<matplotlib.axes.Subplot instance at 0xd54b26c>, <matplotlib.axes.Axes instance at 0xd3f0b2c>]
|
||||
```
|
||||
|
||||
Because the figure maintains the concept of the "current axes" (see
|
||||
[``Figure.gca``](https://matplotlib.orgapi/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure.gca) and
|
||||
[``Figure.sca``](https://matplotlib.orgapi/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure.sca)) to support the
|
||||
pylab/pyplot state machine, you should not insert or remove axes
|
||||
directly from the axes list, but rather use the
|
||||
[``add_subplot()``](https://matplotlib.orgapi/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure.add_subplot) and
|
||||
[``add_axes()``](https://matplotlib.orgapi/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure.add_axes) methods to insert, and the
|
||||
[``delaxes()``](https://matplotlib.orgapi/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure.delaxes) method to delete. You are
|
||||
free however, to iterate over the list of axes or index into it to get
|
||||
access to ``Axes`` instances you want to customize. Here is an
|
||||
example which turns all the axes grids on:
|
||||
|
||||
``` python
|
||||
for ax in fig.axes:
|
||||
ax.grid(True)
|
||||
```
|
||||
|
||||
The figure also has its own text, lines, patches and images, which you
|
||||
can use to add primitives directly. The default coordinate system for
|
||||
the ``Figure`` will simply be in pixels (which is not usually what you
|
||||
want) but you can control this by setting the transform property of
|
||||
the ``Artist`` you are adding to the figure.
|
||||
|
||||
More useful is "figure coordinates" where (0, 0) is the bottom-left of
|
||||
the figure and (1, 1) is the top-right of the figure which you can
|
||||
obtain by setting the ``Artist`` transform to ``fig.transFigure``:
|
||||
|
||||
``` python
|
||||
import matplotlib.lines as lines
|
||||
|
||||
fig = plt.figure()
|
||||
|
||||
l1 = lines.Line2D([0, 1], [0, 1], transform=fig.transFigure, figure=fig)
|
||||
l2 = lines.Line2D([0, 1], [1, 0], transform=fig.transFigure, figure=fig)
|
||||
fig.lines.extend([l1, l2])
|
||||
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
Here is a summary of the Artists the figure contains
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Figure attribute
|
||||
Description
|
||||
|
||||
|
||||
|
||||
axes
|
||||
A list of Axes instances (includes Subplot)
|
||||
|
||||
patch
|
||||
The Rectangle background
|
||||
|
||||
images
|
||||
A list of FigureImages patches - useful for raw pixel display
|
||||
|
||||
legends
|
||||
A list of Figure Legend instances (different from Axes.legends)
|
||||
|
||||
lines
|
||||
A list of Figure Line2D instances (rarely used, see Axes.lines)
|
||||
|
||||
patches
|
||||
A list of Figure patches (rarely used, see Axes.patches)
|
||||
|
||||
texts
|
||||
A list Figure Text instances
|
||||
|
||||
|
||||
|
||||
|
||||
### Axes container
|
||||
|
||||
The [``matplotlib.axes.Axes``](https://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes) is the center of the matplotlib
|
||||
universe -- it contains the vast majority of all the ``Artists`` used
|
||||
in a figure with many helper methods to create and add these
|
||||
``Artists`` to itself, as well as helper methods to access and
|
||||
customize the ``Artists`` it contains. Like the
|
||||
[``Figure``](https://matplotlib.orgapi/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure), it contains a
|
||||
[``Patch``](https://matplotlib.orgapi/_as_gen/matplotlib.patches.Patch.html#matplotlib.patches.Patch)
|
||||
``patch`` which is a
|
||||
[``Rectangle``](https://matplotlib.orgapi/_as_gen/matplotlib.patches.Rectangle.html#matplotlib.patches.Rectangle) for Cartesian coordinates and a
|
||||
[``Circle``](https://matplotlib.orgapi/_as_gen/matplotlib.patches.Circle.html#matplotlib.patches.Circle) for polar coordinates; this patch
|
||||
determines the shape, background and border of the plotting region:
|
||||
|
||||
``` python
|
||||
ax = fig.add_subplot(111)
|
||||
rect = ax.patch # a Rectangle instance
|
||||
rect.set_facecolor('green')
|
||||
```
|
||||
|
||||
When you call a plotting method, e.g., the canonical
|
||||
[``plot()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.plot.html#matplotlib.axes.Axes.plot) and pass in arrays or lists of
|
||||
values, the method will create a [``matplotlib.lines.Line2D()``](https://matplotlib.orgapi/_as_gen/matplotlib.lines.Line2D.html#matplotlib.lines.Line2D)
|
||||
instance, update the line with all the ``Line2D`` properties passed as
|
||||
keyword arguments, add the line to the ``Axes.lines`` container, and returns it to you:
|
||||
|
||||
``` python
|
||||
In [213]: x, y = np.random.rand(2, 100)
|
||||
|
||||
In [214]: line, = ax.plot(x, y, '-', color='blue', linewidth=2)
|
||||
```
|
||||
|
||||
``plot`` returns a list of lines because you can pass in multiple x, y
|
||||
pairs to plot, and we are unpacking the first element of the length
|
||||
one list into the line variable. The line has been added to the
|
||||
``Axes.lines`` list:
|
||||
|
||||
``` python
|
||||
In [229]: print(ax.lines)
|
||||
[<matplotlib.lines.Line2D instance at 0xd378b0c>]
|
||||
```
|
||||
|
||||
Similarly, methods that create patches, like
|
||||
[``bar()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.bar.html#matplotlib.axes.Axes.bar) creates a list of rectangles, will
|
||||
add the patches to the ``Axes.patches`` list:
|
||||
|
||||
``` python
|
||||
In [233]: n, bins, rectangles = ax.hist(np.random.randn(1000), 50, facecolor='yellow')
|
||||
|
||||
In [234]: rectangles
|
||||
Out[234]: <a list of 50 Patch objects>
|
||||
|
||||
In [235]: print(len(ax.patches))
|
||||
```
|
||||
|
||||
You should not add objects directly to the ``Axes.lines`` or
|
||||
``Axes.patches`` lists unless you know exactly what you are doing,
|
||||
because the ``Axes`` needs to do a few things when it creates and adds
|
||||
an object. It sets the figure and axes property of the ``Artist``, as
|
||||
well as the default ``Axes`` transformation (unless a transformation
|
||||
is set). It also inspects the data contained in the ``Artist`` to
|
||||
update the data structures controlling auto-scaling, so that the view
|
||||
limits can be adjusted to contain the plotted data. You can,
|
||||
nonetheless, create objects yourself and add them directly to the
|
||||
``Axes`` using helper methods like
|
||||
[``add_line()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.add_line.html#matplotlib.axes.Axes.add_line) and
|
||||
[``add_patch()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.add_patch.html#matplotlib.axes.Axes.add_patch). Here is an annotated
|
||||
interactive session illustrating what is going on:
|
||||
|
||||
``` python
|
||||
In [262]: fig, ax = plt.subplots()
|
||||
|
||||
# create a rectangle instance
|
||||
In [263]: rect = matplotlib.patches.Rectangle( (1,1), width=5, height=12)
|
||||
|
||||
# by default the axes instance is None
|
||||
In [264]: print(rect.get_axes())
|
||||
None
|
||||
|
||||
# and the transformation instance is set to the "identity transform"
|
||||
In [265]: print(rect.get_transform())
|
||||
<Affine object at 0x13695544>
|
||||
|
||||
# now we add the Rectangle to the Axes
|
||||
In [266]: ax.add_patch(rect)
|
||||
|
||||
# and notice that the ax.add_patch method has set the axes
|
||||
# instance
|
||||
In [267]: print(rect.get_axes())
|
||||
Axes(0.125,0.1;0.775x0.8)
|
||||
|
||||
# and the transformation has been set too
|
||||
In [268]: print(rect.get_transform())
|
||||
<Affine object at 0x15009ca4>
|
||||
|
||||
# the default axes transformation is ax.transData
|
||||
In [269]: print(ax.transData)
|
||||
<Affine object at 0x15009ca4>
|
||||
|
||||
# notice that the xlimits of the Axes have not been changed
|
||||
In [270]: print(ax.get_xlim())
|
||||
(0.0, 1.0)
|
||||
|
||||
# but the data limits have been updated to encompass the rectangle
|
||||
In [271]: print(ax.dataLim.bounds)
|
||||
(1.0, 1.0, 5.0, 12.0)
|
||||
|
||||
# we can manually invoke the auto-scaling machinery
|
||||
In [272]: ax.autoscale_view()
|
||||
|
||||
# and now the xlim are updated to encompass the rectangle
|
||||
In [273]: print(ax.get_xlim())
|
||||
(1.0, 6.0)
|
||||
|
||||
# we have to manually force a figure draw
|
||||
In [274]: ax.figure.canvas.draw()
|
||||
```
|
||||
|
||||
There are many, many ``Axes`` helper methods for creating primitive
|
||||
``Artists`` and adding them to their respective containers. The table
|
||||
below summarizes a small sampling of them, the kinds of ``Artist`` they
|
||||
create, and where they store them
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Helper method
|
||||
Artist
|
||||
Container
|
||||
|
||||
|
||||
|
||||
ax.annotate - text annotations
|
||||
Annotate
|
||||
ax.texts
|
||||
|
||||
ax.bar - bar charts
|
||||
Rectangle
|
||||
ax.patches
|
||||
|
||||
ax.errorbar - error bar plots
|
||||
Line2D and Rectangle
|
||||
ax.lines and ax.patches
|
||||
|
||||
ax.fill - shared area
|
||||
Polygon
|
||||
ax.patches
|
||||
|
||||
ax.hist - histograms
|
||||
Rectangle
|
||||
ax.patches
|
||||
|
||||
ax.imshow - image data
|
||||
AxesImage
|
||||
ax.images
|
||||
|
||||
ax.legend - axes legends
|
||||
Legend
|
||||
ax.legends
|
||||
|
||||
ax.plot - xy plots
|
||||
Line2D
|
||||
ax.lines
|
||||
|
||||
ax.scatter - scatter charts
|
||||
PolygonCollection
|
||||
ax.collections
|
||||
|
||||
ax.text - text
|
||||
Text
|
||||
ax.texts
|
||||
|
||||
|
||||
|
||||
|
||||
In addition to all of these ``Artists``, the ``Axes`` contains two
|
||||
important ``Artist`` containers: the [``XAxis``](https://matplotlib.orgapi/axis_api.html#matplotlib.axis.XAxis)
|
||||
and [``YAxis``](https://matplotlib.orgapi/axis_api.html#matplotlib.axis.YAxis), which handle the drawing of the
|
||||
ticks and labels. These are stored as instance variables
|
||||
``xaxis`` and
|
||||
``yaxis``. The ``XAxis`` and ``YAxis``
|
||||
containers will be detailed below, but note that the ``Axes`` contains
|
||||
many helper methods which forward calls on to the
|
||||
[``Axis``](https://matplotlib.orgapi/axis_api.html#matplotlib.axis.Axis) instances so you often do not need to
|
||||
work with them directly unless you want to. For example, you can set
|
||||
the font color of the ``XAxis`` ticklabels using the ``Axes`` helper
|
||||
method:
|
||||
|
||||
``` python
|
||||
for label in ax.get_xticklabels():
|
||||
label.set_color('orange')
|
||||
```
|
||||
|
||||
Below is a summary of the Artists that the Axes contains
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Axes attribute
|
||||
Description
|
||||
|
||||
|
||||
|
||||
artists
|
||||
A list of Artist instances
|
||||
|
||||
patch
|
||||
Rectangle instance for Axes background
|
||||
|
||||
collections
|
||||
A list of Collection instances
|
||||
|
||||
images
|
||||
A list of AxesImage
|
||||
|
||||
legends
|
||||
A list of Legend instances
|
||||
|
||||
lines
|
||||
A list of Line2D instances
|
||||
|
||||
patches
|
||||
A list of Patch instances
|
||||
|
||||
texts
|
||||
A list of Text instances
|
||||
|
||||
xaxis
|
||||
matplotlib.axis.XAxis instance
|
||||
|
||||
yaxis
|
||||
matplotlib.axis.YAxis instance
|
||||
|
||||
|
||||
|
||||
|
||||
### Axis containers
|
||||
|
||||
The [``matplotlib.axis.Axis``](https://matplotlib.orgapi/axis_api.html#matplotlib.axis.Axis) instances handle the drawing of the
|
||||
tick lines, the grid lines, the tick labels and the axis label. You
|
||||
can configure the left and right ticks separately for the y-axis, and
|
||||
the upper and lower ticks separately for the x-axis. The ``Axis``
|
||||
also stores the data and view intervals used in auto-scaling, panning
|
||||
and zooming, as well as the [``Locator``](https://matplotlib.orgapi/ticker_api.html#matplotlib.ticker.Locator) and
|
||||
[``Formatter``](https://matplotlib.orgapi/ticker_api.html#matplotlib.ticker.Formatter) instances which control where
|
||||
the ticks are placed and how they are represented as strings.
|
||||
|
||||
Each ``Axis`` object contains a ``label`` attribute
|
||||
(this is what [``pyplot``](https://matplotlib.orgapi/_as_gen/matplotlib.pyplot.html#module-matplotlib.pyplot) modifies in calls to
|
||||
[``xlabel()``](https://matplotlib.orgapi/_as_gen/matplotlib.pyplot.xlabel.html#matplotlib.pyplot.xlabel) and [``ylabel()``](https://matplotlib.orgapi/_as_gen/matplotlib.pyplot.ylabel.html#matplotlib.pyplot.ylabel)) as
|
||||
well as a list of major and minor ticks. The ticks are
|
||||
[``XTick``](https://matplotlib.orgapi/axis_api.html#matplotlib.axis.XTick) and [``YTick``](https://matplotlib.orgapi/axis_api.html#matplotlib.axis.YTick) instances,
|
||||
which contain the actual line and text primitives that render the ticks and
|
||||
ticklabels. Because the ticks are dynamically created as needed (e.g., when
|
||||
panning and zooming), you should access the lists of major and minor ticks
|
||||
through their accessor methods [``get_major_ticks()``](https://matplotlib.orgapi/_as_gen/matplotlib.axis.Axis.get_major_ticks.html#matplotlib.axis.Axis.get_major_ticks)
|
||||
and [``get_minor_ticks()``](https://matplotlib.orgapi/_as_gen/matplotlib.axis.Axis.get_minor_ticks.html#matplotlib.axis.Axis.get_minor_ticks). Although the ticks contain
|
||||
all the primitives and will be covered below, ``Axis`` instances have accessor
|
||||
methods that return the tick lines, tick labels, tick locations etc.:
|
||||
|
||||
``` python
|
||||
fig, ax = plt.subplots()
|
||||
axis = ax.xaxis
|
||||
axis.get_ticklocs()
|
||||
```
|
||||
|
||||

|
||||
|
||||
``` python
|
||||
axis.get_ticklabels()
|
||||
```
|
||||
|
||||
note there are twice as many ticklines as labels because by
|
||||
|
||||
``` python
|
||||
axis.get_ticklines()
|
||||
```
|
||||
|
||||
by default you get the major ticks back
|
||||
|
||||
``` python
|
||||
axis.get_ticklines()
|
||||
```
|
||||
|
||||
but you can also ask for the minor ticks
|
||||
|
||||
``` python
|
||||
axis.get_ticklines(minor=True)
|
||||
|
||||
# Here is a summary of some of the useful accessor methods of the ``Axis``
|
||||
# (these have corresponding setters where useful, such as
|
||||
# set_major_formatter)
|
||||
#
|
||||
# ====================== =========================================================
|
||||
# Accessor method Description
|
||||
# ====================== =========================================================
|
||||
# get_scale The scale of the axis, e.g., 'log' or 'linear'
|
||||
# get_view_interval The interval instance of the axis view limits
|
||||
# get_data_interval The interval instance of the axis data limits
|
||||
# get_gridlines A list of grid lines for the Axis
|
||||
# get_label The axis label - a Text instance
|
||||
# get_ticklabels A list of Text instances - keyword minor=True|False
|
||||
# get_ticklines A list of Line2D instances - keyword minor=True|False
|
||||
# get_ticklocs A list of Tick locations - keyword minor=True|False
|
||||
# get_major_locator The matplotlib.ticker.Locator instance for major ticks
|
||||
# get_major_formatter The matplotlib.ticker.Formatter instance for major ticks
|
||||
# get_minor_locator The matplotlib.ticker.Locator instance for minor ticks
|
||||
# get_minor_formatter The matplotlib.ticker.Formatter instance for minor ticks
|
||||
# get_major_ticks A list of Tick instances for major ticks
|
||||
# get_minor_ticks A list of Tick instances for minor ticks
|
||||
# grid Turn the grid on or off for the major or minor ticks
|
||||
# ====================== =========================================================
|
||||
#
|
||||
# Here is an example, not recommended for its beauty, which customizes
|
||||
# the axes and tick properties
|
||||
|
||||
# plt.figure creates a matplotlib.figure.Figure instance
|
||||
fig = plt.figure()
|
||||
rect = fig.patch # a rectangle instance
|
||||
rect.set_facecolor('lightgoldenrodyellow')
|
||||
|
||||
ax1 = fig.add_axes([0.1, 0.3, 0.4, 0.4])
|
||||
rect = ax1.patch
|
||||
rect.set_facecolor('lightslategray')
|
||||
|
||||
|
||||
for label in ax1.xaxis.get_ticklabels():
|
||||
# label is a Text instance
|
||||
label.set_color('red')
|
||||
label.set_rotation(45)
|
||||
label.set_fontsize(16)
|
||||
|
||||
for line in ax1.yaxis.get_ticklines():
|
||||
# line is a Line2D instance
|
||||
line.set_color('green')
|
||||
line.set_markersize(25)
|
||||
line.set_markeredgewidth(3)
|
||||
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Tick containers
|
||||
|
||||
The [``matplotlib.axis.Tick``](https://matplotlib.orgapi/axis_api.html#matplotlib.axis.Tick) is the final container object in our
|
||||
descent from the [``Figure``](https://matplotlib.orgapi/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure) to the
|
||||
[``Axes``](https://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes) to the [``Axis``](https://matplotlib.orgapi/axis_api.html#matplotlib.axis.Axis)
|
||||
to the [``Tick``](https://matplotlib.orgapi/axis_api.html#matplotlib.axis.Tick). The ``Tick`` contains the tick
|
||||
and grid line instances, as well as the label instances for the upper
|
||||
and lower ticks. Each of these is accessible directly as an attribute
|
||||
of the ``Tick``.
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Tick attribute
|
||||
Description
|
||||
|
||||
|
||||
|
||||
tick1line
|
||||
Line2D instance
|
||||
|
||||
tick2line
|
||||
Line2D instance
|
||||
|
||||
gridline
|
||||
Line2D instance
|
||||
|
||||
label1
|
||||
Text instance
|
||||
|
||||
label2
|
||||
Text instance
|
||||
|
||||
|
||||
|
||||
|
||||
Here is an example which sets the formatter for the right side ticks with
|
||||
dollar signs and colors them green on the right side of the yaxis
|
||||
|
||||
``` python
|
||||
import matplotlib.ticker as ticker
|
||||
|
||||
# Fixing random state for reproducibility
|
||||
np.random.seed(19680801)
|
||||
|
||||
fig, ax = plt.subplots()
|
||||
ax.plot(100*np.random.rand(20))
|
||||
|
||||
formatter = ticker.FormatStrFormatter('$%1.2f')
|
||||
ax.yaxis.set_major_formatter(formatter)
|
||||
|
||||
for tick in ax.yaxis.get_major_ticks():
|
||||
tick.label1.set_visible(False)
|
||||
tick.label2.set_visible(True)
|
||||
tick.label2.set_color('green')
|
||||
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Download
|
||||
|
||||
- [Download Python source code: artists.py](https://matplotlib.org/_downloads/a7b58a13e5ee2b59b31d49c2baa9f139/artists.py)
|
||||
- [Download Jupyter notebook: artists.ipynb](https://matplotlib.org/_downloads/c328d03dcd3b9dae9a8b3f008c82073b/artists.ipynb)
|
||||
|
||||
Reference in New Issue
Block a user