matplotlib & pandas

This commit is contained in:
estomm
2020-09-26 22:03:11 +08:00
parent 73cc328c81
commit d31be4f219
599 changed files with 99925 additions and 0 deletions

335
Python/matplotlab/README.md Normal file
View File

@@ -0,0 +1,335 @@
---
sidebarDepth: 3
sidebar: auto
---
# 教程
本页面包含有关使用Matplotlib的更深入的指南。
它分为初学者、中级和高级部分,以及涵盖特定主题的部分。
有关更短的示例,请参阅我们的[示例陈列馆](/gallery/index.html)。
您还可以在我们的[用户指南](https://matplotlib.org/contents.html)中找到[外部资源](/resources/index.html)
和[常见问题解答](/faq/index.html)。
## 序言
这些教程涵盖了使用 Matplotlib 创建可视化的基础知识,以及有效使用软件包的一些最佳实践。
<div class="gallery-examples-list">
<ul>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_usage_thumb.png" />
</div>
<div class="text">
<a href="introductory/usage.html#sphx-glr-tutorials-introductory-usage-py">Usage Guide</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_pyplot_thumb.png" />
</div>
<div class="text">
<a href="introductory/pyplot.html#sphx-glr-tutorials-introductory-pyplot-py">Pyplot tutorial</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_sample_plots_thumb.png" />
</div>
<div class="text">
<a href="introductory/sample_plots.html#sphx-glr-tutorials-introductory-sample-plots-py">Sample plots in Matplotlib</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_images_thumb.png" />
</div>
<div class="text">
<a href="introductory/images.html#sphx-glr-tutorials-introductory-images-py">Image tutorial</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_lifecycle_thumb.png" />
</div>
<div class="text">
<a href="introductory/lifecycle.html#sphx-glr-tutorials-introductory-lifecycle-py">The Lifecycle of a Plot</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_customizing_thumb.png" />
</div>
<div class="text">
<a href="introductory/customizing.html#sphx-glr-tutorials-introductory-customizing-py">Customizing Matplotlib with style sheets and rcParams</a>
</div>
</li>
</ul>
</div>
## 中级
这些教程涵盖了Matplotlib中一些更复杂的类和函数。它们对于特定的自定义和复杂的可视化很有用。
<div class="gallery-examples-list">
<ul>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_artists_thumb.png" />
</div>
<div class="text">
<a href="intermediate/artists.html#sphx-glr-tutorials-intermediate-artists-py">Artist tutorial</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_legend_guide_thumb.png" />
</div>
<div class="text">
<a href="intermediate/legend_guide.html#sphx-glr-tutorials-intermediate-legend-guide-py">Legend guide</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_color_cycle_thumb.png" />
</div>
<div class="text">
<a href="intermediate/color_cycle.html#sphx-glr-tutorials-intermediate-color-cycle-py">Styling with cycler</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_gridspec_thumb.png" />
</div>
<div class="text">
<a href="intermediate/gridspec.html#sphx-glr-tutorials-intermediate-gridspec-py">Customizing Figure Layouts Using GridSpec and Other Functions</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_constrainedlayout_guide_thumb.png" />
</div>
<div class="text">
<a href="intermediate/constrainedlayout_guide.html#sphx-glr-tutorials-intermediate-constrainedlayout-guide-py">Constrained Layout Guide</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_tight_layout_guide_thumb.png" />
</div>
<div class="text">
<a href="intermediate/tight_layout_guide.html#sphx-glr-tutorials-intermediate-tight-layout-guide-py">Tight Layout guide</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_imshow_extent_thumb.png" />
</div>
<div class="text">
<a href="intermediate/imshow_extent.html#sphx-glr-tutorials-intermediate-imshow-extent-py">origin and extent in imshow</a>
</div>
</li>
</ul>
</div>
## 高级
这些教程涵盖了经验丰富的Matplotlib用户和开发人员的高级主题。
<div class="gallery-examples-list">
<ul>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_path_tutorial_thumb.png" />
</div>
<div class="text">
<a href="advanced/path_tutorial.html#sphx-glr-tutorials-advanced-path-tutorial-py">Path Tutorial</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_patheffects_guide_thumb.png" />
</div>
<div class="text">
<a href="advanced/patheffects_guide.html#sphx-glr-tutorials-advanced-patheffects-guide-py">Path effects guide</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_transforms_tutorial_thumb.png" />
</div>
<div class="text">
<a href="advanced/transforms_tutorial.html#sphx-glr-tutorials-advanced-transforms-tutorial-py">Transformations Tutorial</a>
</div>
</li>
</ul>
</div>
## 颜色
Matplotlib支持使用多种颜色和颜色图可视化信息。 这些教程涵盖了这些颜色图的外观,如何创建自己的颜色图以及如何针对用例自定义颜色图的基础知识。
有关更多信息,请参见[示例陈列馆](/gallery/index.htm)。
<div class="gallery-examples-list">
<ul>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_colors_thumb.png" />
</div>
<div class="text">
<a href="colors/colors.html#sphx-glr-tutorials-colors-colors-py">Specifying Colors</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_colorbar_only_thumb.png" />
</div>
<div class="text">
<a href="colors/colorbar_only.html#sphx-glr-tutorials-colors-colorbar-only-py">Customized Colorbars Tutorial</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_colormap-manipulation_thumb.png" />
</div>
<div class="text">
<a href="colors/colormap-manipulation.html#sphx-glr-tutorials-colors-colormap-manipulation-py">Creating Colormaps in Matplotlib</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_colormapnorms_thumb.png" />
</div>
<div class="text">
<a href="colors/colormapnorms.html#sphx-glr-tutorials-colors-colormapnorms-py">Colormap Normalization</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_colormaps_thumb.png" />
</div>
<div class="text">
<a href="colors/colormaps.html#sphx-glr-tutorials-colors-colormaps-py">Choosing Colormaps in Matplotlib</a>
</div>
</li>
</ul>
</div>
## 文本
matplotlib具有广泛的文本支持包括对数学表达式的支持对栅格和矢量输出的truetype支持
任意旋转的换行符分隔文本以及unicode支持。
这些教程涵盖了在Matplotlib中处理文本的基础知识。
<div class="gallery-examples-list">
<ul>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_text_intro_thumb.png" />
</div>
<div class="text">
<a href="text/text_intro.html#sphx-glr-tutorials-text-text-intro-py">Text in Matplotlib Plots</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_text_props_thumb.png" />
</div>
<div class="text">
<a href="text/text_props.html#sphx-glr-tutorials-text-text-props-py">Text properties and layout</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_annotations_thumb.png" />
</div>
<div class="text">
<a href="text/annotations.html#sphx-glr-tutorials-text-annotations-py">Annotations</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_mathtext_thumb.png" />
</div>
<div class="text">
<a href="text/mathtext.html#sphx-glr-tutorials-text-mathtext-py">Writing mathematical expressions</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_pgf_thumb.png" />
</div>
<div class="text">
<a href="text/pgf.html#sphx-glr-tutorials-text-pgf-py">Typesetting With XeLaTeX/LuaLaTeX</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_usetex_thumb.png" />
</div>
<div class="text">
<a href="text/usetex.html#sphx-glr-tutorials-text-usetex-py">Text rendering With LaTeX</a>
</div>
</li>
</ul>
</div>
## 小工具
这些教程涵盖了旨在扩展 Matplotlib 功能以实现特定目标的工具包。
<div class="gallery-examples-list">
<ul>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_axes_grid_thumb.png" />
</div>
<div class="text">
<a href="toolkits/axes_grid.html#sphx-glr-tutorials-toolkits-axes-grid-py">Overview of axes_grid1 toolkit</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_axisartist_thumb.png" />
</div>
<div class="text">
<a href="toolkits/axisartist.html#sphx-glr-tutorials-toolkits-axisartist-py">Overview of axisartist toolkit</a>
</div>
</li>
<li>
<div class="poster">
<img src="https://matplotlib.org/_images/sphx_glr_mplot3d_thumb.png" />
</div>
<div class="text">
<a href="toolkits/mplot3d.html#sphx-glr-tutorials-toolkits-mplot3d-py">The mplot3d Toolkit</a>
</div>
</li>
</ul>
</div>

View File

@@ -0,0 +1,265 @@
---
sidebarDepth: 3
sidebar: auto
---
# Path Tutorial
Defining paths in your Matplotlib visualization.
The object underlying all of the ``matplotlib.patch`` objects is
the [``Path``](https://matplotlib.orgapi/path_api.html#matplotlib.path.Path), which supports the standard set of
moveto, lineto, curveto commands to draw simple and compound outlines
consisting of line segments and splines. The ``Path`` is instantiated
with a (N,2) array of (x,y) vertices, and a N-length array of path
codes. For example to draw the unit rectangle from (0,0) to (1,1), we
could use this code
``` python
import matplotlib.pyplot as plt
from matplotlib.path import Path
import matplotlib.patches as patches
verts = [
(0., 0.), # left, bottom
(0., 1.), # left, top
(1., 1.), # right, top
(1., 0.), # right, bottom
(0., 0.), # ignored
]
codes = [
Path.MOVETO,
Path.LINETO,
Path.LINETO,
Path.LINETO,
Path.CLOSEPOLY,
]
path = Path(verts, codes)
fig, ax = plt.subplots()
patch = patches.PathPatch(path, facecolor='orange', lw=2)
ax.add_patch(patch)
ax.set_xlim(-2, 2)
ax.set_ylim(-2, 2)
plt.show()
```
![sphx_glr_path_tutorial_001](https://matplotlib.org/_images/sphx_glr_path_tutorial_001.png)
The following path codes are recognized
---
Code
Vertices
Description
STOP
1 (ignored)
A marker for the end of the entire path (currently not required and ignored)
MOVETO
1
Pick up the pen and move to the given vertex.
LINETO
1
Draw a line from the current position to the given vertex.
CURVE3
2 (1 control point, 1 endpoint)
Draw a quadratic Bézier curve from the current position, with the given control point, to the given end point.
CURVE4
3 (2 control points, 1 endpoint)
Draw a cubic Bézier curve from the current position, with the given control points, to the given end point.
CLOSEPOLY
1 (point itself is ignored)
Draw a line segment to the start point of the current polyline.
## Bézier example
Some of the path components require multiple vertices to specify them:
for example CURVE 3 is a [bézier](https://en.wikipedia.org/wiki/B%C3%A9zier_curve) curve with one
control point and one end point, and CURVE4 has three vertices for the
two control points and the end point. The example below shows a
CURVE4 Bézier spline -- the bézier curve will be contained in the
convex hull of the start point, the two control points, and the end
point
``` python
verts = [
(0., 0.), # P0
(0.2, 1.), # P1
(1., 0.8), # P2
(0.8, 0.), # P3
]
codes = [
Path.MOVETO,
Path.CURVE4,
Path.CURVE4,
Path.CURVE4,
]
path = Path(verts, codes)
fig, ax = plt.subplots()
patch = patches.PathPatch(path, facecolor='none', lw=2)
ax.add_patch(patch)
xs, ys = zip(*verts)
ax.plot(xs, ys, 'x--', lw=2, color='black', ms=10)
ax.text(-0.05, -0.05, 'P0')
ax.text(0.15, 1.05, 'P1')
ax.text(1.05, 0.85, 'P2')
ax.text(0.85, -0.05, 'P3')
ax.set_xlim(-0.1, 1.1)
ax.set_ylim(-0.1, 1.1)
plt.show()
```
![sphx_glr_path_tutorial_002](https://matplotlib.org/_images/sphx_glr_path_tutorial_002.png)
## Compound paths
All of the simple patch primitives in matplotlib, Rectangle, Circle,
Polygon, etc, are implemented with simple path. Plotting functions
like [``hist()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.hist.html#matplotlib.axes.Axes.hist) and
[``bar()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.bar.html#matplotlib.axes.Axes.bar), which create a number of
primitives, e.g., a bunch of Rectangles, can usually be implemented more
efficiently using a compound path. The reason ``bar`` creates a list
of rectangles and not a compound path is largely historical: the
[``Path``](https://matplotlib.orgapi/path_api.html#matplotlib.path.Path) code is comparatively new and ``bar``
predates it. While we could change it now, it would break old code,
so here we will cover how to create compound paths, replacing the
functionality in bar, in case you need to do so in your own code for
efficiency reasons, e.g., you are creating an animated bar plot.
We will make the histogram chart by creating a series of rectangles
for each histogram bar: the rectangle width is the bin width and the
rectangle height is the number of datapoints in that bin. First we'll
create some random normally distributed data and compute the
histogram. Because numpy returns the bin edges and not centers, the
length of ``bins`` is 1 greater than the length of ``n`` in the
example below:
``` python
# histogram our data with numpy
data = np.random.randn(1000)
n, bins = np.histogram(data, 100)
```
We'll now extract the corners of the rectangles. Each of the
``left``, ``bottom``, etc, arrays below is ``len(n)``, where ``n`` is
the array of counts for each histogram bar:
``` python
# get the corners of the rectangles for the histogram
left = np.array(bins[:-1])
right = np.array(bins[1:])
bottom = np.zeros(len(left))
top = bottom + n
```
Now we have to construct our compound path, which will consist of a
series of ``MOVETO``, ``LINETO`` and ``CLOSEPOLY`` for each rectangle.
For each rectangle, we need 5 vertices: 1 for the ``MOVETO``, 3 for
the ``LINETO``, and 1 for the ``CLOSEPOLY``. As indicated in the
table above, the vertex for the closepoly is ignored but we still need
it to keep the codes aligned with the vertices:
``` python
nverts = nrects*(1+3+1)
verts = np.zeros((nverts, 2))
codes = np.ones(nverts, int) * path.Path.LINETO
codes[0::5] = path.Path.MOVETO
codes[4::5] = path.Path.CLOSEPOLY
verts[0::5,0] = left
verts[0::5,1] = bottom
verts[1::5,0] = left
verts[1::5,1] = top
verts[2::5,0] = right
verts[2::5,1] = top
verts[3::5,0] = right
verts[3::5,1] = bottom
```
All that remains is to create the path, attach it to a
``PathPatch``, and add it to our axes:
``` python
barpath = path.Path(verts, codes)
patch = patches.PathPatch(barpath, facecolor='green',
edgecolor='yellow', alpha=0.5)
ax.add_patch(patch)
```
``` python
import numpy as np
import matplotlib.patches as patches
import matplotlib.path as path
fig, ax = plt.subplots()
# Fixing random state for reproducibility
np.random.seed(19680801)
# histogram our data with numpy
data = np.random.randn(1000)
n, bins = np.histogram(data, 100)
# get the corners of the rectangles for the histogram
left = np.array(bins[:-1])
right = np.array(bins[1:])
bottom = np.zeros(len(left))
top = bottom + n
nrects = len(left)
nverts = nrects*(1+3+1)
verts = np.zeros((nverts, 2))
codes = np.ones(nverts, int) * path.Path.LINETO
codes[0::5] = path.Path.MOVETO
codes[4::5] = path.Path.CLOSEPOLY
verts[0::5, 0] = left
verts[0::5, 1] = bottom
verts[1::5, 0] = left
verts[1::5, 1] = top
verts[2::5, 0] = right
verts[2::5, 1] = top
verts[3::5, 0] = right
verts[3::5, 1] = bottom
barpath = path.Path(verts, codes)
patch = patches.PathPatch(barpath, facecolor='green',
edgecolor='yellow', alpha=0.5)
ax.add_patch(patch)
ax.set_xlim(left[0], right[-1])
ax.set_ylim(bottom.min(), top.max())
plt.show()
```
![sphx_glr_path_tutorial_003](https://matplotlib.org/_images/sphx_glr_path_tutorial_003.png)
## Download
- [Download Python source code: path_tutorial.py](https://matplotlib.org/_downloads/ec90dd07bc241d860eb972db796c96bc/path_tutorial.py)
- [Download Jupyter notebook: path_tutorial.ipynb](https://matplotlib.org/_downloads/da8cacf827800cc7398495a527da865d/path_tutorial.ipynb)

View File

@@ -0,0 +1,122 @@
---
sidebarDepth: 3
sidebar: auto
---
# Path effects guide
Defining paths that objects follow on a canvas.
Matplotlib's [``patheffects``](#module-matplotlib.patheffects) module provides functionality to
apply a multiple draw stage to any Artist which can be rendered via a
[``Path``](https://matplotlib.orgapi/path_api.html#matplotlib.path.Path).
Artists which can have a path effect applied to them include [``Patch``](https://matplotlib.orgapi/_as_gen/matplotlib.patches.Patch.html#matplotlib.patches.Patch),
[``Line2D``](https://matplotlib.orgapi/_as_gen/matplotlib.lines.Line2D.html#matplotlib.lines.Line2D), [``Collection``](https://matplotlib.orgapi/collections_api.html#matplotlib.collections.Collection) and even
[``Text``](https://matplotlib.orgapi/text_api.html#matplotlib.text.Text). Each artist's path effects can be controlled via the
``set_path_effects`` method ([``set_path_effects``](https://matplotlib.orgapi/_as_gen/matplotlib.artist.Artist.set_path_effects.html#matplotlib.artist.Artist.set_path_effects)), which takes
an iterable of [``AbstractPathEffect``](https://matplotlib.orgapi/patheffects_api.html#matplotlib.patheffects.AbstractPathEffect) instances.
The simplest path effect is the [``Normal``](https://matplotlib.orgapi/patheffects_api.html#matplotlib.patheffects.Normal) effect, which simply
draws the artist without any effect:
``` python
import matplotlib.pyplot as plt
import matplotlib.patheffects as path_effects
fig = plt.figure(figsize=(5, 1.5))
text = fig.text(0.5, 0.5, 'Hello path effects world!\nThis is the normal '
'path effect.\nPretty dull, huh?',
ha='center', va='center', size=20)
text.set_path_effects([path_effects.Normal()])
plt.show()
```
![sphx_glr_patheffects_guide_001](https://matplotlib.org/_images/sphx_glr_patheffects_guide_001.png)
Whilst the plot doesn't look any different to what you would expect without any path
effects, the drawing of the text now been changed to use the path effects
framework, opening up the possibilities for more interesting examples.
## Adding a shadow
A far more interesting path effect than [``Normal``](https://matplotlib.orgapi/patheffects_api.html#matplotlib.patheffects.Normal) is the
drop-shadow, which we can apply to any of our path based artists. The classes
[``SimplePatchShadow``](https://matplotlib.orgapi/patheffects_api.html#matplotlib.patheffects.SimplePatchShadow) and
[``SimpleLineShadow``](https://matplotlib.orgapi/patheffects_api.html#matplotlib.patheffects.SimpleLineShadow) do precisely this by drawing either a filled
patch or a line patch below the original artist:
``` python
import matplotlib.patheffects as path_effects
text = plt.text(0.5, 0.5, 'Hello path effects world!',
path_effects=[path_effects.withSimplePatchShadow()])
plt.plot([0, 3, 2, 5], linewidth=5, color='blue',
path_effects=[path_effects.SimpleLineShadow(),
path_effects.Normal()])
plt.show()
```
![sphx_glr_patheffects_guide_002](https://matplotlib.org/_images/sphx_glr_patheffects_guide_002.png)
Notice the two approaches to setting the path effects in this example. The
first uses the ``with*`` classes to include the desired functionality automatically
followed with the "normal" effect, whereas the latter explicitly defines the two path
effects to draw.
## Making an artist stand out
One nice way of making artists visually stand out is to draw an outline in a bold
color below the actual artist. The [``Stroke``](https://matplotlib.orgapi/patheffects_api.html#matplotlib.patheffects.Stroke) path effect
makes this a relatively simple task:
``` python
fig = plt.figure(figsize=(7, 1))
text = fig.text(0.5, 0.5, 'This text stands out because of\n'
'its black border.', color='white',
ha='center', va='center', size=30)
text.set_path_effects([path_effects.Stroke(linewidth=3, foreground='black'),
path_effects.Normal()])
plt.show()
```
![sphx_glr_patheffects_guide_003](https://matplotlib.org/_images/sphx_glr_patheffects_guide_003.png)
It is important to note that this effect only works because we have drawn the text
path twice; once with a thick black line, and then once with the original text
path on top.
You may have noticed that the keywords to [``Stroke``](https://matplotlib.orgapi/patheffects_api.html#matplotlib.patheffects.Stroke) and
[``SimplePatchShadow``](https://matplotlib.orgapi/patheffects_api.html#matplotlib.patheffects.SimplePatchShadow) and [``SimpleLineShadow``](https://matplotlib.orgapi/patheffects_api.html#matplotlib.patheffects.SimpleLineShadow) are not the usual Artist
keywords (such as ``facecolor`` and ``edgecolor`` etc.). This is because with these
path effects we are operating at lower level of matplotlib. In fact, the keywords
which are accepted are those for a [``matplotlib.backend_bases.GraphicsContextBase``](https://matplotlib.orgapi/backend_bases_api.html#matplotlib.backend_bases.GraphicsContextBase)
instance, which have been designed for making it easy to create new backends - and not
for its user interface.
## Greater control of the path effect artist
As already mentioned, some of the path effects operate at a lower level than most users
will be used to, meaning that setting keywords such as ``facecolor`` and ``edgecolor``
raise an AttributeError. Luckily there is a generic [``PathPatchEffect``](https://matplotlib.orgapi/patheffects_api.html#matplotlib.patheffects.PathPatchEffect) path effect
which creates a [``PathPatch``](https://matplotlib.orgapi/_as_gen/matplotlib.patches.PathPatch.html#matplotlib.patches.PathPatch) class with the original path.
The keywords to this effect are identical to those of [``PathPatch``](https://matplotlib.orgapi/_as_gen/matplotlib.patches.PathPatch.html#matplotlib.patches.PathPatch):
``` python
fig = plt.figure(figsize=(8, 1))
t = fig.text(0.02, 0.5, 'Hatch shadow', fontsize=75, weight=1000, va='center')
t.set_path_effects([path_effects.PathPatchEffect(offset=(4, -4), hatch='xxxx',
facecolor='gray'),
path_effects.PathPatchEffect(edgecolor='white', linewidth=1.1,
facecolor='black')])
plt.show()
```
![sphx_glr_patheffects_guide_004](https://matplotlib.org/_images/sphx_glr_patheffects_guide_004.png)
## Download
- [Download Python source code: patheffects_guide.py](https://matplotlib.org/_downloads/b0857128f7eceadab81240baf9185710/patheffects_guide.py)
- [Download Jupyter notebook: patheffects_guide.ipynb](https://matplotlib.org/_downloads/d678b58ce777643e611577a5aafc6f8d/patheffects_guide.ipynb)

View File

@@ -0,0 +1,615 @@
---
sidebarDepth: 3
sidebar: auto
---
# Transformations Tutorial
Like any graphics packages, Matplotlib is built on top of a
transformation framework to easily move between coordinate systems,
the userland ``data`` coordinate system, the ``axes`` coordinate system,
the ``figure`` coordinate system, and the ``display`` coordinate system.
In 95% of your plotting, you won't need to think about this, as it
happens under the hood, but as you push the limits of custom figure
generation, it helps to have an understanding of these objects so you
can reuse the existing transformations Matplotlib makes available to
you, or create your own (see [``matplotlib.transforms``](https://matplotlib.orgapi/transformations.html#module-matplotlib.transforms)). The table
below summarizes the some useful coordinate systems, the transformation
object you should use to work in that coordinate system, and the
description of that system. In the ``Transformation Object`` column,
``ax`` is a [``Axes``](https://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes) instance, and ``fig`` is a
[``Figure``](https://matplotlib.orgapi/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure) instance.
---
Coordinates
Transformation object
Description
"data"
ax.transData
The coordinate system for the data,
controlled by xlim and ylim.
"axes"
ax.trans[Axes](https://matplotlib.org/../api/axes_api.html#matplotlib.axes.Axes)
The coordinate system of the
Axes; (0, 0)
is bottom left of the axes, and
(1, 1) is top right of the axes.
"figure"
fig.trans[[Figure](https://matplotlib.org/../api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure)](https://matplotlib.org/../api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure)
The coordinate system of the
Figure; (0, 0) is bottom left
of the figure, and (1, 1) is top
right of the figure.
"figure-inches"
fig.dpi_scale_trans
The coordinate system of the
Figure in inches; (0, 0) is
bottom left of the figure, and
(width, height) is the top right
of the figure in inches.
"display"
None, or
IdentityTransform()
The pixel coordinate system of the
display window; (0, 0) is bottom
left of the window, and (width,
height) is top right of the
display window in pixels.
"xaxis",
"yaxis"
ax.get_xaxis_transform(),
ax.get_yaxis_transform()
Blended coordinate systems; use
data coordinates on one of the axis
and axes coordinates on the other.
All of the transformation objects in the table above take inputs in
their coordinate system, and transform the input to the ``display``
coordinate system. That is why the ``display`` coordinate system has
``None`` for the ``Transformation Object`` column -- it already is in
display coordinates. The transformations also know how to invert
themselves, to go from ``display`` back to the native coordinate system.
This is particularly useful when processing events from the user
interface, which typically occur in display space, and you want to
know where the mouse click or key-press occurred in your data
coordinate system.
Note that specifying objects in ``display`` coordinates will change their
location if the ``dpi`` of the figure changes. This can cause confusion when
printing or changing screen resolution, because the object can change location
and size. Therefore it is most common
for artists placed in an axes or figure to have their transform set to
something *other* than the [``IdentityTransform()``](https://matplotlib.orgapi/transformations.html#matplotlib.transforms.IdentityTransform); the default when
an artist is placed on an axes using ``add_artist`` is for the
transform to be ``ax.transData``.
## Data coordinates
Let's start with the most commonly used coordinate, the ``data``
coordinate system. Whenever you add data to the axes, Matplotlib
updates the datalimits, most commonly updated with the
[``set_xlim()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.set_xlim.html#matplotlib.axes.Axes.set_xlim) and
[``set_ylim()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.set_ylim.html#matplotlib.axes.Axes.set_ylim) methods. For example, in the
figure below, the data limits stretch from 0 to 10 on the x-axis, and
-1 to 1 on the y-axis.
``` python
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
x = np.arange(0, 10, 0.005)
y = np.exp(-x/2.) * np.sin(2*np.pi*x)
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_xlim(0, 10)
ax.set_ylim(-1, 1)
plt.show()
```
![sphx_glr_transforms_tutorial_001](https://matplotlib.org/_images/sphx_glr_transforms_tutorial_001.png)
You can use the ``ax.transData`` instance to transform from your
``data`` to your ``display`` coordinate system, either a single point or a
sequence of points as shown below:
``` python
In [14]: type(ax.transData)
Out[14]: <class 'matplotlib.transforms.CompositeGenericTransform'>
In [15]: ax.transData.transform((5, 0))
Out[15]: array([ 335.175, 247. ])
In [16]: ax.transData.transform([(5, 0), (1, 2)])
Out[16]:
array([[ 335.175, 247. ],
[ 132.435, 642.2 ]])
```
You can use the [``inverted()``](https://matplotlib.orgapi/transformations.html#matplotlib.transforms.Transform.inverted)
method to create a transform which will take you from display to data
coordinates:
``` python
In [41]: inv = ax.transData.inverted()
In [42]: type(inv)
Out[42]: <class 'matplotlib.transforms.CompositeGenericTransform'>
In [43]: inv.transform((335.175, 247.))
Out[43]: array([ 5., 0.])
```
If your are typing along with this tutorial, the exact values of the
display coordinates may differ if you have a different window size or
dpi setting. Likewise, in the figure below, the display labeled
points are probably not the same as in the ipython session because the
documentation figure size defaults are different.
``` python
x = np.arange(0, 10, 0.005)
y = np.exp(-x/2.) * np.sin(2*np.pi*x)
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_xlim(0, 10)
ax.set_ylim(-1, 1)
xdata, ydata = 5, 0
xdisplay, ydisplay = ax.transData.transform_point((xdata, ydata))
bbox = dict(boxstyle="round", fc="0.8")
arrowprops = dict(
arrowstyle="->",
connectionstyle="angle,angleA=0,angleB=90,rad=10")
offset = 72
ax.annotate('data = (%.1f, %.1f)' % (xdata, ydata),
(xdata, ydata), xytext=(-2*offset, offset), textcoords='offset points',
bbox=bbox, arrowprops=arrowprops)
disp = ax.annotate('display = (%.1f, %.1f)' % (xdisplay, ydisplay),
(xdisplay, ydisplay), xytext=(0.5*offset, -offset),
xycoords='figure pixels',
textcoords='offset points',
bbox=bbox, arrowprops=arrowprops)
plt.show()
```
![sphx_glr_transforms_tutorial_002](https://matplotlib.org/_images/sphx_glr_transforms_tutorial_002.png)
::: tip Note
If you run the source code in the example above in a GUI backend,
you may also find that the two arrows for the ``data`` and ``display``
annotations do not point to exactly the same point. This is because
the display point was computed before the figure was displayed, and
the GUI backend may slightly resize the figure when it is created.
The effect is more pronounced if you resize the figure yourself.
This is one good reason why you rarely want to work in display
space, but you can connect to the ``'on_draw'``
[``Event``](https://matplotlib.orgapi/backend_bases_api.html#matplotlib.backend_bases.Event) to update figure
coordinates on figure draws; see [Event handling and picking](https://matplotlib.orgusers/event_handling.html#event-handling-tutorial).
:::
When you change the x or y limits of your axes, the data limits are
updated so the transformation yields a new display point. Note that
when we just change the ylim, only the y-display coordinate is
altered, and when we change the xlim too, both are altered. More on
this later when we talk about the
[``Bbox``](https://matplotlib.orgapi/transformations.html#matplotlib.transforms.Bbox).
``` python
In [54]: ax.transData.transform((5, 0))
Out[54]: array([ 335.175, 247. ])
In [55]: ax.set_ylim(-1, 2)
Out[55]: (-1, 2)
In [56]: ax.transData.transform((5, 0))
Out[56]: array([ 335.175 , 181.13333333])
In [57]: ax.set_xlim(10, 20)
Out[57]: (10, 20)
In [58]: ax.transData.transform((5, 0))
Out[58]: array([-171.675 , 181.13333333])
```
## Axes coordinates
After the ``data`` coordinate system, ``axes`` is probably the second most
useful coordinate system. Here the point (0, 0) is the bottom left of
your axes or subplot, (0.5, 0.5) is the center, and (1.0, 1.0) is the
top right. You can also refer to points outside the range, so (-0.1,
1.1) is to the left and above your axes. This coordinate system is
extremely useful when placing text in your axes, because you often
want a text bubble in a fixed, location, e.g., the upper left of the axes
pane, and have that location remain fixed when you pan or zoom. Here
is a simple example that creates four panels and labels them 'A', 'B',
'C', 'D' as you often see in journals.
``` python
fig = plt.figure()
for i, label in enumerate(('A', 'B', 'C', 'D')):
ax = fig.add_subplot(2, 2, i+1)
ax.text(0.05, 0.95, label, transform=ax.transAxes,
fontsize=16, fontweight='bold', va='top')
plt.show()
```
![sphx_glr_transforms_tutorial_003](https://matplotlib.org/_images/sphx_glr_transforms_tutorial_003.png)
You can also make lines or patches in the axes coordinate system, but
this is less useful in my experience than using ``ax.transAxes`` for
placing text. Nonetheless, here is a silly example which plots some
random dots in ``data`` space, and overlays a semi-transparent
[``Circle``](https://matplotlib.orgapi/_as_gen/matplotlib.patches.Circle.html#matplotlib.patches.Circle) centered in the middle of the axes
with a radius one quarter of the axes -- if your axes does not
preserve aspect ratio (see [``set_aspect()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.set_aspect.html#matplotlib.axes.Axes.set_aspect)),
this will look like an ellipse. Use the pan/zoom tool to move around,
or manually change the data xlim and ylim, and you will see the data
move, but the circle will remain fixed because it is not in ``data``
coordinates and will always remain at the center of the axes.
``` python
fig, ax = plt.subplots()
x, y = 10*np.random.rand(2, 1000)
ax.plot(x, y, 'go', alpha=0.2) # plot some data in data coordinates
circ = mpatches.Circle((0.5, 0.5), 0.25, transform=ax.transAxes,
facecolor='blue', alpha=0.75)
ax.add_patch(circ)
plt.show()
```
![sphx_glr_transforms_tutorial_004](https://matplotlib.org/_images/sphx_glr_transforms_tutorial_004.png)
## Blended transformations
Drawing in ``blended`` coordinate spaces which mix ``axes`` with ``data``
coordinates is extremely useful, for example to create a horizontal
span which highlights some region of the y-data but spans across the
x-axis regardless of the data limits, pan or zoom level, etc. In fact
these blended lines and spans are so useful, we have built in
functions to make them easy to plot (see
[``axhline()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.axhline.html#matplotlib.axes.Axes.axhline),
[``axvline()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.axvline.html#matplotlib.axes.Axes.axvline),
[``axhspan()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.axhspan.html#matplotlib.axes.Axes.axhspan),
[``axvspan()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.axvspan.html#matplotlib.axes.Axes.axvspan)) but for didactic purposes we
will implement the horizontal span here using a blended
transformation. This trick only works for separable transformations,
like you see in normal Cartesian coordinate systems, but not on
inseparable transformations like the
[``PolarTransform``](https://matplotlib.orgapi/projections_api.html#matplotlib.projections.polar.PolarAxes.PolarTransform).
``` python
import matplotlib.transforms as transforms
fig, ax = plt.subplots()
x = np.random.randn(1000)
ax.hist(x, 30)
ax.set_title(r'$\sigma=1 \/ \dots \/ \sigma=2$', fontsize=16)
# the x coords of this transformation are data, and the
# y coord are axes
trans = transforms.blended_transform_factory(
ax.transData, ax.transAxes)
# highlight the 1..2 stddev region with a span.
# We want x to be in data coordinates and y to
# span from 0..1 in axes coords
rect = mpatches.Rectangle((1, 0), width=1, height=1,
transform=trans, color='yellow',
alpha=0.5)
ax.add_patch(rect)
plt.show()
```
![sphx_glr_transforms_tutorial_005](https://matplotlib.org/_images/sphx_glr_transforms_tutorial_005.png)
::: tip Note
The blended transformations where x is in data coords and y in axes
coordinates is so useful that we have helper methods to return the
versions mpl uses internally for drawing ticks, ticklabels, etc.
The methods are [``matplotlib.axes.Axes.get_xaxis_transform()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.get_xaxis_transform.html#matplotlib.axes.Axes.get_xaxis_transform) and
[``matplotlib.axes.Axes.get_yaxis_transform()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.get_yaxis_transform.html#matplotlib.axes.Axes.get_yaxis_transform). So in the example
above, the call to
[``blended_transform_factory()``](https://matplotlib.orgapi/transformations.html#matplotlib.transforms.blended_transform_factory) can be
replaced by ``get_xaxis_transform``:
``` python
trans = ax.get_xaxis_transform()
```
:::
## Plotting in physical units
Sometimes we want an object to be a certain physical size on the plot.
Here we draw the same circle as above, but in physical units. If done
interactively, you can see that changing the size of the figure does
not change the offset of the circle from the lower-left corner,
does not change its size, and the circle remains a circle regardless of
the aspect ratio of the axes.
``` python
fig, ax = plt.subplots(figsize=(5, 4))
x, y = 10*np.random.rand(2, 1000)
ax.plot(x, y*10., 'go', alpha=0.2) # plot some data in data coordinates
# add a circle in fixed-units
circ = mpatches.Circle((2.5, 2), 1.0, transform=fig.dpi_scale_trans,
facecolor='blue', alpha=0.75)
ax.add_patch(circ)
plt.show()
```
![sphx_glr_transforms_tutorial_006](https://matplotlib.org/_images/sphx_glr_transforms_tutorial_006.png)
If we change the figure size, the circle does not change its absolute
position and is cropped.
``` python
fig, ax = plt.subplots(figsize=(7, 2))
x, y = 10*np.random.rand(2, 1000)
ax.plot(x, y*10., 'go', alpha=0.2) # plot some data in data coordinates
# add a circle in fixed-units
circ = mpatches.Circle((2.5, 2), 1.0, transform=fig.dpi_scale_trans,
facecolor='blue', alpha=0.75)
ax.add_patch(circ)
plt.show()
```
![sphx_glr_transforms_tutorial_007](https://matplotlib.org/_images/sphx_glr_transforms_tutorial_007.png)
Another use is putting a patch with a set physical dimension around a
data point on the axes. Here we add together two transforms. The
first sets the scaling of how large the ellipse should be and the second
sets its position. The ellipse is then placed at the origin, and then
we use the helper transform [``ScaledTranslation``](https://matplotlib.orgapi/transformations.html#matplotlib.transforms.ScaledTranslation)
to move it
to the right place in the ``ax.transData`` coordinate system.
This helper is instantiated with:
``` python
trans = ScaledTranslation(xt, yt, scale_trans)
```
where ``xt`` and ``yt`` are the translation offsets, and ``scale_trans`` is
a transformation which scales ``xt`` and ``yt`` at transformation time
before applying the offsets.
Note the use of the plus operator on the transforms below.
This code says: first apply the scale transformation ``fig.dpi_scale_trans``
to make the ellipse the proper size, but still centered at (0, 0),
and then translate the data to ``xdata[0]`` and ``ydata[0]`` in data space.
In interactive use, the ellipse stays the same size even if the
axes limits are changed via zoom.
``` python
fig, ax = plt.subplots()
xdata, ydata = (0.2, 0.7), (0.5, 0.5)
ax.plot(xdata, ydata, "o")
ax.set_xlim((0, 1))
trans = (fig.dpi_scale_trans +
transforms.ScaledTranslation(xdata[0], ydata[0], ax.transData))
# plot an ellipse around the point that is 150 x 130 points in diameter...
circle = mpatches.Ellipse((0, 0), 150/72, 130/72, angle=40,
fill=None, transform=trans)
ax.add_patch(circle)
plt.show()
```
![sphx_glr_transforms_tutorial_008](https://matplotlib.org/_images/sphx_glr_transforms_tutorial_008.png)
::: tip Note
The order of transformation matters. Here the ellipse
is given the right dimensions in display space *first* and then moved
in data space to the correct spot.
If we had done the ``ScaledTranslation`` first, then
``xdata[0]`` and ``ydata[0]`` would
first be transformed to ``display`` coordinates (``[ 358.4  475.2]`` on
a 200-dpi monitor) and then those coordinates
would be scaled by ``fig.dpi_scale_trans`` pushing the center of
the ellipse well off the screen (i.e. ``[ 71680.  95040.]``).
:::
## Using offset transforms to create a shadow effect
Another use of [``ScaledTranslation``](https://matplotlib.orgapi/transformations.html#matplotlib.transforms.ScaledTranslation) is to create
a new transformation that is
offset from another transformation, e.g., to place one object shifted a
bit relative to another object. Typically you want the shift to be in
some physical dimension, like points or inches rather than in data
coordinates, so that the shift effect is constant at different zoom
levels and dpi settings.
One use for an offset is to create a shadow effect, where you draw one
object identical to the first just to the right of it, and just below
it, adjusting the zorder to make sure the shadow is drawn first and
then the object it is shadowing above it.
Here we apply the transforms in the *opposite* order to the use of
[``ScaledTranslation``](https://matplotlib.orgapi/transformations.html#matplotlib.transforms.ScaledTranslation) above. The plot is
first made in data units (``ax.transData``) and then shifted by
``dx`` and ``dy`` points using ``fig.dpi_scale_trans``. (In typography,
a`point <[https://en.wikipedia.org/wiki/Point_%28typography%29](https://en.wikipedia.org/wiki/Point_%28typography%29)>`_ is
1/72 inches, and by specifying your offsets in points, your figure
will look the same regardless of the dpi resolution it is saved in.)
``` python
fig, ax = plt.subplots()
# make a simple sine wave
x = np.arange(0., 2., 0.01)
y = np.sin(2*np.pi*x)
line, = ax.plot(x, y, lw=3, color='blue')
# shift the object over 2 points, and down 2 points
dx, dy = 2/72., -2/72.
offset = transforms.ScaledTranslation(dx, dy, fig.dpi_scale_trans)
shadow_transform = ax.transData + offset
# now plot the same data with our offset transform;
# use the zorder to make sure we are below the line
ax.plot(x, y, lw=3, color='gray',
transform=shadow_transform,
zorder=0.5*line.get_zorder())
ax.set_title('creating a shadow effect with an offset transform')
plt.show()
```
![sphx_glr_transforms_tutorial_009](https://matplotlib.org/_images/sphx_glr_transforms_tutorial_009.png)
::: tip Note
The dpi and inches offset is a
common-enough use case that we have a special helper function to
create it in [``matplotlib.transforms.offset_copy()``](https://matplotlib.orgapi/transformations.html#matplotlib.transforms.offset_copy), which returns
a new transform with an added offset. So above we could have done:
``` python
shadow_transform = transforms.offset_copy(ax.transData,
fig=fig, dx, dy, units='inches')
```
:::
## The transformation pipeline
The ``ax.transData`` transform we have been working with in this
tutorial is a composite of three different transformations that
comprise the transformation pipeline from ``data`` -> ``display``
coordinates. Michael Droettboom implemented the transformations
framework, taking care to provide a clean API that segregated the
nonlinear projections and scales that happen in polar and logarithmic
plots, from the linear affine transformations that happen when you pan
and zoom. There is an efficiency here, because you can pan and zoom
in your axes which affects the affine transformation, but you may not
need to compute the potentially expensive nonlinear scales or
projections on simple navigation events. It is also possible to
multiply affine transformation matrices together, and then apply them
to coordinates in one step. This is not true of all possible
transformations.
Here is how the ``ax.transData`` instance is defined in the basic
separable axis [``Axes``](https://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes) class:
``` python
self.transData = self.transScale + (self.transLimits + self.transAxes)
```
We've been introduced to the ``transAxes`` instance above in
[Axes coordinates](#axes-coords), which maps the (0, 0), (1, 1) corners of the
axes or subplot bounding box to ``display`` space, so let's look at
these other two pieces.
``self.transLimits`` is the transformation that takes you from
``data`` to ``axes`` coordinates; i.e., it maps your view xlim and ylim
to the unit space of the axes (and ``transAxes`` then takes that unit
space to display space). We can see this in action here
``` python
In [80]: ax = subplot(111)
In [81]: ax.set_xlim(0, 10)
Out[81]: (0, 10)
In [82]: ax.set_ylim(-1, 1)
Out[82]: (-1, 1)
In [84]: ax.transLimits.transform((0, -1))
Out[84]: array([ 0., 0.])
In [85]: ax.transLimits.transform((10, -1))
Out[85]: array([ 1., 0.])
In [86]: ax.transLimits.transform((10, 1))
Out[86]: array([ 1., 1.])
In [87]: ax.transLimits.transform((5, 0))
Out[87]: array([ 0.5, 0.5])
```
and we can use this same inverted transformation to go from the unit
``axes`` coordinates back to ``data`` coordinates.
``` python
In [90]: inv.transform((0.25, 0.25))
Out[90]: array([ 2.5, -0.5])
```
The final piece is the ``self.transScale`` attribute, which is
responsible for the optional non-linear scaling of the data, e.g., for
logarithmic axes. When an Axes is initially setup, this is just set to
the identity transform, since the basic Matplotlib axes has linear
scale, but when you call a logarithmic scaling function like
[``semilogx()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.semilogx.html#matplotlib.axes.Axes.semilogx) or explicitly set the scale to
logarithmic with [``set_xscale()``](https://matplotlib.orgapi/_as_gen/matplotlib.axes.Axes.set_xscale.html#matplotlib.axes.Axes.set_xscale), then the
``ax.transScale`` attribute is set to handle the nonlinear projection.
The scales transforms are properties of the respective ``xaxis`` and
``yaxis`` [``Axis``](https://matplotlib.orgapi/axis_api.html#matplotlib.axis.Axis) instances. For example, when
you call ``ax.set_xscale('log')``, the xaxis updates its scale to a
[``matplotlib.scale.LogScale``](https://matplotlib.orgapi/scale_api.html#matplotlib.scale.LogScale) instance.
For non-separable axes the PolarAxes, there is one more piece to
consider, the projection transformation. The ``transData``
[``matplotlib.projections.polar.PolarAxes``](https://matplotlib.orgapi/projections_api.html#matplotlib.projections.polar.PolarAxes) is similar to that for
the typical separable matplotlib Axes, with one additional piece
``transProjection``:
``` python
self.transData = self.transScale + self.transProjection + \
(self.transProjectionAffine + self.transAxes)
```
``transProjection`` handles the projection from the space,
e.g., latitude and longitude for map data, or radius and theta for polar
data, to a separable Cartesian coordinate system. There are several
projection examples in the ``matplotlib.projections`` package, and the
best way to learn more is to open the source for those packages and
see how to make your own, since Matplotlib supports extensible axes
and projections. Michael Droettboom has provided a nice tutorial
example of creating a Hammer projection axes; see
[Custom projection](https://matplotlib.orggallery/misc/custom_projection.html).
**Total running time of the script:** ( 0 minutes 1.328 seconds)
## Download
- [Download Python source code: transforms_tutorial.py](https://matplotlib.org/_downloads/1d1cf62db33a4554c487470c01670fe5/transforms_tutorial.py)
- [Download Jupyter notebook: transforms_tutorial.ipynb](https://matplotlib.org/_downloads/b6ea9be45c260fbed02d8e2d9b2e4549/transforms_tutorial.ipynb)

View File

@@ -0,0 +1,123 @@
---
sidebarDepth: 3
sidebar: auto
---
# Customized Colorbars Tutorial
This tutorial shows how to build colorbars without an attached plot.
## Customized Colorbars
[``ColorbarBase``](https://matplotlib.orgapi/colorbar_api.html#matplotlib.colorbar.ColorbarBase) puts a colorbar in a specified axes,
and can make a colorbar for a given colormap; it does not need a mappable
object like an image. In this tutorial we will explore what can be done with
standalone colorbar.
### Basic continuous colorbar
Set the colormap and norm to correspond to the data for which the colorbar
will be used. Then create the colorbar by calling
[``ColorbarBase``](https://matplotlib.orgapi/colorbar_api.html#matplotlib.colorbar.ColorbarBase) and specify axis, colormap, norm
and orientation as parameters. Here we create a basic continuous colorbar
with ticks and labels. For more information see the
[``colorbar``](https://matplotlib.orgapi/colorbar_api.html#module-matplotlib.colorbar) API.
``` python
import matplotlib.pyplot as plt
import matplotlib as mpl
fig, ax = plt.subplots(figsize=(6, 1))
fig.subplots_adjust(bottom=0.5)
cmap = mpl.cm.cool
norm = mpl.colors.Normalize(vmin=5, vmax=10)
cb1 = mpl.colorbar.ColorbarBase(ax, cmap=cmap,
norm=norm,
orientation='horizontal')
cb1.set_label('Some Units')
fig.show()
```
![sphx_glr_colorbar_only_001](https://matplotlib.org/_images/sphx_glr_colorbar_only_001.png)
### Discrete intervals colorbar
The second example illustrates the use of a
[``ListedColormap``](https://matplotlib.orgapi/_as_gen/matplotlib.colors.ListedColormap.html#matplotlib.colors.ListedColormap) which generates a colormap from a
set of listed colors, ``colors.BoundaryNorm()`` which generates a colormap
index based on discrete intervals and extended ends to show the "over" and
"under" value colors. Over and under are used to display data outside of the
normalized [0,1] range. Here we pass colors as gray shades as a string
encoding a float in the 0-1 range.
If a [``ListedColormap``](https://matplotlib.orgapi/_as_gen/matplotlib.colors.ListedColormap.html#matplotlib.colors.ListedColormap) is used, the length of the
bounds array must be one greater than the length of the color list. The
bounds must be monotonically increasing.
This time we pass some more arguments in addition to previous arguments to
[``ColorbarBase``](https://matplotlib.orgapi/colorbar_api.html#matplotlib.colorbar.ColorbarBase). For the out-of-range values to
display on the colorbar, we have to use the *extend* keyword argument. To use
*extend*, you must specify two extra boundaries. Finally spacing argument
ensures that intervals are shown on colorbar proportionally.
``` python
fig, ax = plt.subplots(figsize=(6, 1))
fig.subplots_adjust(bottom=0.5)
cmap = mpl.colors.ListedColormap(['red', 'green', 'blue', 'cyan'])
cmap.set_over('0.25')
cmap.set_under('0.75')
bounds = [1, 2, 4, 7, 8]
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
cb2 = mpl.colorbar.ColorbarBase(ax, cmap=cmap,
norm=norm,
boundaries=[0] + bounds + [13],
extend='both',
ticks=bounds,
spacing='proportional',
orientation='horizontal')
cb2.set_label('Discrete intervals, some other units')
fig.show()
```
![sphx_glr_colorbar_only_002](https://matplotlib.org/_images/sphx_glr_colorbar_only_002.png)
### Colorbar with custom extension lengths
Here we illustrate the use of custom length colorbar extensions, used on a
colorbar with discrete intervals. To make the length of each extension the
same as the length of the interior colors, use ``extendfrac='auto'``.
``` python
fig, ax = plt.subplots(figsize=(6, 1))
fig.subplots_adjust(bottom=0.5)
cmap = mpl.colors.ListedColormap(['royalblue', 'cyan',
'yellow', 'orange'])
cmap.set_over('red')
cmap.set_under('blue')
bounds = [-1.0, -0.5, 0.0, 0.5, 1.0]
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
cb3 = mpl.colorbar.ColorbarBase(ax, cmap=cmap,
norm=norm,
boundaries=[-10] + bounds + [10],
extend='both',
extendfrac='auto',
ticks=bounds,
spacing='uniform',
orientation='horizontal')
cb3.set_label('Custom extension lengths, some other units')
fig.show()
```
![sphx_glr_colorbar_only_003](https://matplotlib.org/_images/sphx_glr_colorbar_only_003.png)
## Download
- [Download Python source code: colorbar_only.py](https://matplotlib.org/_downloads/23690f47313380b801750e3adc4c317e/colorbar_only.py)
- [Download Jupyter notebook: colorbar_only.ipynb](https://matplotlib.org/_downloads/4d3eb6ad2b03a5eb988f576ea050f104/colorbar_only.ipynb)

View File

@@ -0,0 +1,311 @@
---
sidebarDepth: 3
sidebar: auto
---
# Creating Colormaps in Matplotlib
Matplotlib has a number of built-in colormaps accessible via
[``matplotlib.cm.get_cmap``](https://matplotlib.orgapi/cm_api.html#matplotlib.cm.get_cmap). There are also external libraries like
[palettable](https://jiffyclub.github.io/palettable/) that have many extra colormaps.
However, we often want to create or manipulate colormaps in Matplotlib.
This can be done using the class [``ListedColormap``](https://matplotlib.orgapi/_as_gen/matplotlib.colors.ListedColormap.html#matplotlib.colors.ListedColormap) and a Nx4 numpy array of
values between 0 and 1 to represent the RGBA values of the colormap. There
is also a [``LinearSegmentedColormap``](https://matplotlib.orgapi/_as_gen/matplotlib.colors.LinearSegmentedColormap.html#matplotlib.colors.LinearSegmentedColormap) class that allows colormaps to be
specified with a few anchor points defining segments, and linearly
interpolating between the anchor points.
## Getting colormaps and accessing their values
First, getting a named colormap, most of which are listed in
[Choosing Colormaps in Matplotlib](colormaps.html) requires the use of
[``matplotlib.cm.get_cmap``](https://matplotlib.orgapi/cm_api.html#matplotlib.cm.get_cmap), which returns a
[``matplotlib.colors.ListedColormap``](https://matplotlib.orgapi/_as_gen/matplotlib.colors.ListedColormap.html#matplotlib.colors.ListedColormap) object. The second argument gives
the size of the list of colors used to define the colormap, and below we
use a modest value of 12 so there are not a lot of values to look at.
``` python
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.colors import ListedColormap, LinearSegmentedColormap
viridis = cm.get_cmap('viridis', 12)
print(viridis)
```
Out:
```
<matplotlib.colors.ListedColormap object at 0x7f7f3c724390>
```
The object ``viridis`` is a callable, that when passed a float between
0 and 1 returns an RGBA value from the colormap:
``` python
print(viridis(0.56))
```
Out:
```
(0.119512, 0.607464, 0.540218, 1.0)
```
The list of colors that comprise the colormap can be directly accessed using
the ``colors`` property,
or it can be accessed indirectly by calling ``viridis`` with an array
of values matching the length of the colormap. Note that the returned list
is in the form of an RGBA Nx4 array, where N is the length of the colormap.
``` python
print('viridis.colors', viridis.colors)
print('viridis(range(12))', viridis(range(12)))
print('viridis(np.linspace(0, 1, 12))', viridis(np.linspace(0, 1, 12)))
```
Out:
```
viridis.colors [[0.267004 0.004874 0.329415 1. ]
[0.283072 0.130895 0.449241 1. ]
[0.262138 0.242286 0.520837 1. ]
[0.220057 0.343307 0.549413 1. ]
[0.177423 0.437527 0.557565 1. ]
[0.143343 0.522773 0.556295 1. ]
[0.119512 0.607464 0.540218 1. ]
[0.166383 0.690856 0.496502 1. ]
[0.319809 0.770914 0.411152 1. ]
[0.525776 0.833491 0.288127 1. ]
[0.762373 0.876424 0.137064 1. ]
[0.993248 0.906157 0.143936 1. ]]
viridis(range(12)) [[0.267004 0.004874 0.329415 1. ]
[0.283072 0.130895 0.449241 1. ]
[0.262138 0.242286 0.520837 1. ]
[0.220057 0.343307 0.549413 1. ]
[0.177423 0.437527 0.557565 1. ]
[0.143343 0.522773 0.556295 1. ]
[0.119512 0.607464 0.540218 1. ]
[0.166383 0.690856 0.496502 1. ]
[0.319809 0.770914 0.411152 1. ]
[0.525776 0.833491 0.288127 1. ]
[0.762373 0.876424 0.137064 1. ]
[0.993248 0.906157 0.143936 1. ]]
viridis(np.linspace(0, 1, 12)) [[0.267004 0.004874 0.329415 1. ]
[0.283072 0.130895 0.449241 1. ]
[0.262138 0.242286 0.520837 1. ]
[0.220057 0.343307 0.549413 1. ]
[0.177423 0.437527 0.557565 1. ]
[0.143343 0.522773 0.556295 1. ]
[0.119512 0.607464 0.540218 1. ]
[0.166383 0.690856 0.496502 1. ]
[0.319809 0.770914 0.411152 1. ]
[0.525776 0.833491 0.288127 1. ]
[0.762373 0.876424 0.137064 1. ]
[0.993248 0.906157 0.143936 1. ]]
```
The colormap is a lookup table, so "oversampling" the colormap returns
nearest-neighbor interpolation (note the repeated colors in the list below)
``` python
print('viridis(np.linspace(0, 1, 15))', viridis(np.linspace(0, 1, 15)))
```
Out:
```
viridis(np.linspace(0, 1, 15)) [[0.267004 0.004874 0.329415 1. ]
[0.267004 0.004874 0.329415 1. ]
[0.283072 0.130895 0.449241 1. ]
[0.262138 0.242286 0.520837 1. ]
[0.220057 0.343307 0.549413 1. ]
[0.177423 0.437527 0.557565 1. ]
[0.143343 0.522773 0.556295 1. ]
[0.119512 0.607464 0.540218 1. ]
[0.119512 0.607464 0.540218 1. ]
[0.166383 0.690856 0.496502 1. ]
[0.319809 0.770914 0.411152 1. ]
[0.525776 0.833491 0.288127 1. ]
[0.762373 0.876424 0.137064 1. ]
[0.993248 0.906157 0.143936 1. ]
[0.993248 0.906157 0.143936 1. ]]
```
## Creating listed colormaps
This is essential the inverse operation of the above where we supply a
Nx4 numpy array with all values between 0 and 1,
to [``ListedColormap``](https://matplotlib.orgapi/_as_gen/matplotlib.colors.ListedColormap.html#matplotlib.colors.ListedColormap) to make a new colormap. This means that
any numpy operations that we can do on a Nx4 array make carpentry of
new colormaps from existing colormaps quite straight forward.
Suppose we want to make the first 25 entries of a 256-length "viridis"
colormap pink for some reason:
``` python
viridis = cm.get_cmap('viridis', 256)
newcolors = viridis(np.linspace(0, 1, 256))
pink = np.array([248/256, 24/256, 148/256, 1])
newcolors[:25, :] = pink
newcmp = ListedColormap(newcolors)
def plot_examples(cms):
"""
helper function to plot two colormaps
"""
np.random.seed(19680801)
data = np.random.randn(30, 30)
fig, axs = plt.subplots(1, 2, figsize=(6, 3), constrained_layout=True)
for [ax, cmap] in zip(axs, cms):
psm = ax.pcolormesh(data, cmap=cmap, rasterized=True, vmin=-4, vmax=4)
fig.colorbar(psm, ax=ax)
plt.show()
plot_examples([viridis, newcmp])
```
![sphx_glr_colormap-manipulation_001](https://matplotlib.org/_images/sphx_glr_colormap-manipulation_001.png)
We can easily reduce the dynamic range of a colormap; here we choose the
middle 0.5 of the colormap. However, we need to interpolate from a larger
colormap, otherwise the new colormap will have repeated values.
``` python
viridisBig = cm.get_cmap('viridis', 512)
newcmp = ListedColormap(viridisBig(np.linspace(0.25, 0.75, 256)))
plot_examples([viridis, newcmp])
```
![sphx_glr_colormap-manipulation_002](https://matplotlib.org/_images/sphx_glr_colormap-manipulation_002.png)
and we can easily concatenate two colormaps:
``` python
top = cm.get_cmap('Oranges_r', 128)
bottom = cm.get_cmap('Blues', 128)
newcolors = np.vstack((top(np.linspace(0, 1, 128)),
bottom(np.linspace(0, 1, 128))))
newcmp = ListedColormap(newcolors, name='OrangeBlue')
plot_examples([viridis, newcmp])
```
![sphx_glr_colormap-manipulation_003](https://matplotlib.org/_images/sphx_glr_colormap-manipulation_003.png)
Of course we need not start from a named colormap, we just need to create
the Nx4 array to pass to [``ListedColormap``](https://matplotlib.orgapi/_as_gen/matplotlib.colors.ListedColormap.html#matplotlib.colors.ListedColormap). Here we create a
brown colormap that goes to white....
``` python
N = 256
vals = np.ones((N, 4))
vals[:, 0] = np.linspace(90/256, 1, N)
vals[:, 1] = np.linspace(39/256, 1, N)
vals[:, 2] = np.linspace(41/256, 1, N)
newcmp = ListedColormap(vals)
plot_examples([viridis, newcmp])
```
![sphx_glr_colormap-manipulation_004](https://matplotlib.org/_images/sphx_glr_colormap-manipulation_004.png)
## Creating linear segmented colormaps
[``LinearSegmentedColormap``](https://matplotlib.orgapi/_as_gen/matplotlib.colors.LinearSegmentedColormap.html#matplotlib.colors.LinearSegmentedColormap) class specifies colormaps using anchor points
between which RGB(A) values are interpolated.
The format to specify these colormaps allows discontinuities at the anchor
points. Each anchor point is specified as a row in a matrix of the
form ``[x[i] yleft[i] yright[i]]``, where ``x[i]`` is the anchor, and
``yleft[i]`` and ``yright[i]`` are the values of the color on either
side of the anchor point.
If there are no discontinuities, then ``yleft[i]=yright[i]``:
``` python
cdict = {'red': [[0.0, 0.0, 0.0],
[0.5, 1.0, 1.0],
[1.0, 1.0, 1.0]],
'green': [[0.0, 0.0, 0.0],
[0.25, 0.0, 0.0],
[0.75, 1.0, 1.0],
[1.0, 1.0, 1.0]],
'blue': [[0.0, 0.0, 0.0],
[0.5, 0.0, 0.0],
[1.0, 1.0, 1.0]]}
def plot_linearmap(cdict):
newcmp = LinearSegmentedColormap('testCmap', segmentdata=cdict, N=256)
rgba = newcmp(np.linspace(0, 1, 256))
fig, ax = plt.subplots(figsize=(4, 3), constrained_layout=True)
col = ['r', 'g', 'b']
for xx in [0.25, 0.5, 0.75]:
ax.axvline(xx, color='0.7', linestyle='--')
for i in range(3):
ax.plot(np.arange(256)/256, rgba[:, i], color=col[i])
ax.set_xlabel('index')
ax.set_ylabel('RGB')
plt.show()
plot_linearmap(cdict)
```
![sphx_glr_colormap-manipulation_005](https://matplotlib.org/_images/sphx_glr_colormap-manipulation_005.png)
In order to make a discontinuity at an anchor point, the third column is
different than the second. The matrix for each of "red", "green", "blue",
and optionally "alpha" is set up as:
``` python
cdict['red'] = [...
[x[i] yleft[i] yright[i]],
[x[i+1] yleft[i+1] yright[i+1]],
...]
```
and for values passed to the colormap between ``x[i]`` and ``x[i+1]``,
the interpolation is between ``yright[i]`` and ``yleft[i+1]``.
In the example below there is a discontinuity in red at 0.5. The
interpolation between 0 and 0.5 goes from 0.3 to 1, and between 0.5 and 1
it goes from 0.9 to 1. Note that red[0, 1], and red[2, 2] are both
superfluous to the interpolation because red[0, 1] is the value to the
left of 0, and red[2, 2] is the value to the right of 1.0.
``` python
cdict['red'] = [[0.0, 0.0, 0.3],
[0.5, 1.0, 0.9],
[1.0, 1.0, 1.0]]
plot_linearmap(cdict)
```
![sphx_glr_colormap-manipulation_006](https://matplotlib.org/_images/sphx_glr_colormap-manipulation_006.png)
### References
The use of the following functions, methods, classes and modules is shown
in this example:
``` python
import matplotlib
matplotlib.axes.Axes.pcolormesh
matplotlib.figure.Figure.colorbar
matplotlib.colors
matplotlib.colors.LinearSegmentedColormap
matplotlib.colors.ListedColormap
matplotlib.cm
matplotlib.cm.get_cmap
```
**Total running time of the script:** ( 0 minutes 2.220 seconds)
## Download
- [Download Python source code: colormap-manipulation.py](https://matplotlib.org/_downloads/f55e73a6ac8441fd68270d3c6f2a7c7c/colormap-manipulation.py)
- [Download Jupyter notebook: colormap-manipulation.ipynb](https://matplotlib.org/_downloads/fd9acfdbb45f341d3bb04199f0868a38/colormap-manipulation.ipynb)

View File

@@ -0,0 +1,281 @@
---
sidebarDepth: 3
sidebar: auto
---
# Colormap Normalization
Objects that use colormaps by default linearly map the colors in the
colormap from data values *vmin* to *vmax*. For example:
``` python
pcm = ax.pcolormesh(x, y, Z, vmin=-1., vmax=1., cmap='RdBu_r')
```
will map the data in *Z* linearly from -1 to +1, so *Z=0* will
give a color at the center of the colormap *RdBu_r* (white in this
case).
Matplotlib does this mapping in two steps, with a normalization from
the input data to [0, 1] occurring first, and then mapping onto the
indices in the colormap. Normalizations are classes defined in the
[``matplotlib.colors()``](https://matplotlib.orgapi/colors_api.html#module-matplotlib.colors) module. The default, linear normalization
is [``matplotlib.colors.Normalize()``](https://matplotlib.orgapi/_as_gen/matplotlib.colors.Normalize.html#matplotlib.colors.Normalize).
Artists that map data to color pass the arguments *vmin* and *vmax* to
construct a [``matplotlib.colors.Normalize()``](https://matplotlib.orgapi/_as_gen/matplotlib.colors.Normalize.html#matplotlib.colors.Normalize) instance, then call it:
``` python
In [1]: import matplotlib as mpl
In [2]: norm = mpl.colors.Normalize(vmin=-1.,vmax=1.)
In [3]: norm(0.)
Out[3]: 0.5
```
However, there are sometimes cases where it is useful to map data to
colormaps in a non-linear fashion.
## Logarithmic
One of the most common transformations is to plot data by taking its logarithm
(to the base-10). This transformation is useful to display changes across
disparate scales. Using [``colors.LogNorm``](https://matplotlib.orgapi/_as_gen/matplotlib.colors.LogNorm.html#matplotlib.colors.LogNorm) normalizes the data via
\(log_{10}\). In the example below, there are two bumps, one much smaller
than the other. Using [``colors.LogNorm``](https://matplotlib.orgapi/_as_gen/matplotlib.colors.LogNorm.html#matplotlib.colors.LogNorm), the shape and location of each bump
can clearly be seen:
``` python
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import matplotlib.cbook as cbook
N = 100
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]
# A low hump with a spike coming out of the top right. Needs to have
# z/colour axis on a log scale so we see both hump and spike. linear
# scale only shows the spike.
Z1 = np.exp(-(X)**2 - (Y)**2)
Z2 = np.exp(-(X * 10)**2 - (Y * 10)**2)
Z = Z1 + 50 * Z2
fig, ax = plt.subplots(2, 1)
pcm = ax[0].pcolor(X, Y, Z,
norm=colors.LogNorm(vmin=Z.min(), vmax=Z.max()),
cmap='PuBu_r')
fig.colorbar(pcm, ax=ax[0], extend='max')
pcm = ax[1].pcolor(X, Y, Z, cmap='PuBu_r')
fig.colorbar(pcm, ax=ax[1], extend='max')
plt.show()
```
![sphx_glr_colormapnorms_001](https://matplotlib.org/_images/sphx_glr_colormapnorms_001.png)
## Symmetric logarithmic
Similarly, it sometimes happens that there is data that is positive
and negative, but we would still like a logarithmic scaling applied to
both. In this case, the negative numbers are also scaled
logarithmically, and mapped to smaller numbers; e.g., if ``vmin=-vmax``,
then they the negative numbers are mapped from 0 to 0.5 and the
positive from 0.5 to 1.
Since the logarithm of values close to zero tends toward infinity, a
small range around zero needs to be mapped linearly. The parameter
*linthresh* allows the user to specify the size of this range
(-*linthresh*, *linthresh*). The size of this range in the colormap is
set by *linscale*. When *linscale* == 1.0 (the default), the space used
for the positive and negative halves of the linear range will be equal
to one decade in the logarithmic range.
``` python
N = 100
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) * 2
fig, ax = plt.subplots(2, 1)
pcm = ax[0].pcolormesh(X, Y, Z,
norm=colors.SymLogNorm(linthresh=0.03, linscale=0.03,
vmin=-1.0, vmax=1.0),
cmap='RdBu_r')
fig.colorbar(pcm, ax=ax[0], extend='both')
pcm = ax[1].pcolormesh(X, Y, Z, cmap='RdBu_r', vmin=-np.max(Z))
fig.colorbar(pcm, ax=ax[1], extend='both')
plt.show()
```
![sphx_glr_colormapnorms_002](https://matplotlib.org/_images/sphx_glr_colormapnorms_002.png)
## Power-law
Sometimes it is useful to remap the colors onto a power-law
relationship (i.e. \(y=x^{\gamma}\), where \(\gamma\) is the
power). For this we use the ``colors.PowerNorm()``. It takes as an
argument *gamma* (*gamma* == 1.0 will just yield the default linear
normalization):
::: tip Note
There should probably be a good reason for plotting the data using
this type of transformation. Technical viewers are used to linear
and logarithmic axes and data transformations. Power laws are less
common, and viewers should explicitly be made aware that they have
been used.
:::
``` python
N = 100
X, Y = np.mgrid[0:3:complex(0, N), 0:2:complex(0, N)]
Z1 = (1 + np.sin(Y * 10.)) * X**(2.)
fig, ax = plt.subplots(2, 1)
pcm = ax[0].pcolormesh(X, Y, Z1, norm=colors.PowerNorm(gamma=0.5),
cmap='PuBu_r')
fig.colorbar(pcm, ax=ax[0], extend='max')
pcm = ax[1].pcolormesh(X, Y, Z1, cmap='PuBu_r')
fig.colorbar(pcm, ax=ax[1], extend='max')
plt.show()
```
![sphx_glr_colormapnorms_003](https://matplotlib.org/_images/sphx_glr_colormapnorms_003.png)
## Discrete bounds
Another normaization that comes with Matplotlib is
``colors.BoundaryNorm()``. In addition to *vmin* and *vmax*, this
takes as arguments boundaries between which data is to be mapped. The
colors are then linearly distributed between these "bounds". For
instance:
``` python
In [4]: import matplotlib.colors as colors
In [5]: bounds = np.array([-0.25, -0.125, 0, 0.5, 1])
In [6]: norm = colors.BoundaryNorm(boundaries=bounds, ncolors=4)
In [7]: print(norm([-0.2,-0.15,-0.02, 0.3, 0.8, 0.99]))
[0 0 1 2 3 3]
```
Note unlike the other norms, this norm returns values from 0 to *ncolors*-1.
``` python
N = 100
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) * 2
fig, ax = plt.subplots(3, 1, figsize=(8, 8))
ax = ax.flatten()
# even bounds gives a contour-like effect
bounds = np.linspace(-1, 1, 10)
norm = colors.BoundaryNorm(boundaries=bounds, ncolors=256)
pcm = ax[0].pcolormesh(X, Y, Z,
norm=norm,
cmap='RdBu_r')
fig.colorbar(pcm, ax=ax[0], extend='both', orientation='vertical')
# uneven bounds changes the colormapping:
bounds = np.array([-0.25, -0.125, 0, 0.5, 1])
norm = colors.BoundaryNorm(boundaries=bounds, ncolors=256)
pcm = ax[1].pcolormesh(X, Y, Z, norm=norm, cmap='RdBu_r')
fig.colorbar(pcm, ax=ax[1], extend='both', orientation='vertical')
pcm = ax[2].pcolormesh(X, Y, Z, cmap='RdBu_r', vmin=-np.max(Z))
fig.colorbar(pcm, ax=ax[2], extend='both', orientation='vertical')
plt.show()
```
![sphx_glr_colormapnorms_004](https://matplotlib.org/_images/sphx_glr_colormapnorms_004.png)
## DivergingNorm: Different mapping on either side of a center
Sometimes we want to have a different colormap on either side of a
conceptual center point, and we want those two colormaps to have
different linear scales. An example is a topographic map where the land
and ocean have a center at zero, but land typically has a greater
elevation range than the water has depth range, and they are often
represented by a different colormap.
``` python
filename = cbook.get_sample_data('topobathy.npz', asfileobj=False)
with np.load(filename) as dem:
topo = dem['topo']
longitude = dem['longitude']
latitude = dem['latitude']
fig, ax = plt.subplots()
# make a colormap that has land and ocean clearly delineated and of the
# same length (256 + 256)
colors_undersea = plt.cm.terrain(np.linspace(0, 0.17, 256))
colors_land = plt.cm.terrain(np.linspace(0.25, 1, 256))
all_colors = np.vstack((colors_undersea, colors_land))
terrain_map = colors.LinearSegmentedColormap.from_list('terrain_map',
all_colors)
# make the norm: Note the center is offset so that the land has more
# dynamic range:
divnorm = colors.DivergingNorm(vmin=-500., vcenter=0, vmax=4000)
pcm = ax.pcolormesh(longitude, latitude, topo, rasterized=True, norm=divnorm,
cmap=terrain_map,)
# Simple geographic plot, set aspect ratio beecause distance between lines of
# longitude depends on latitude.
ax.set_aspect(1 / np.cos(np.deg2rad(49)))
fig.colorbar(pcm, shrink=0.6)
plt.show()
```
![sphx_glr_colormapnorms_005](https://matplotlib.org/_images/sphx_glr_colormapnorms_005.png)
## Custom normalization: Manually implement two linear ranges
The [``DivergingNorm``](https://matplotlib.orgapi/_as_gen/matplotlib.colors.DivergingNorm.html#matplotlib.colors.DivergingNorm) described above makes a useful example for
defining your own norm.
``` python
class MidpointNormalize(colors.Normalize):
def __init__(self, vmin=None, vmax=None, vcenter=None, clip=False):
self.vcenter = vcenter
colors.Normalize.__init__(self, vmin, vmax, clip)
def __call__(self, value, clip=None):
# I'm ignoring masked values and all kinds of edge cases to make a
# simple example...
x, y = [self.vmin, self.vcenter, self.vmax], [0, 0.5, 1]
return np.ma.masked_array(np.interp(value, x, y))
fig, ax = plt.subplots()
midnorm = MidpointNormalize(vmin=-500., vcenter=0, vmax=4000)
pcm = ax.pcolormesh(longitude, latitude, topo, rasterized=True, norm=midnorm,
cmap=terrain_map)
ax.set_aspect(1 / np.cos(np.deg2rad(49)))
fig.colorbar(pcm, shrink=0.6, extend='both')
plt.show()
```
![sphx_glr_colormapnorms_006](https://matplotlib.org/_images/sphx_glr_colormapnorms_006.png)
**Total running time of the script:** ( 0 minutes 1.895 seconds)
## Download
- [Download Python source code: colormapnorms.py](https://matplotlib.org/_downloads/56fa91958fd427757e621c21de870bda/colormapnorms.py)
- [Download Jupyter notebook: colormapnorms.ipynb](https://matplotlib.org/_downloads/59a7c8f3db252ae16cd43fd50d6a004c/colormapnorms.ipynb)

View File

@@ -0,0 +1,521 @@
---
sidebarDepth: 3
sidebar: auto
---
# Choosing Colormaps in Matplotlib
Matplotlib has a number of built-in colormaps accessible via
[``matplotlib.cm.get_cmap``](https://matplotlib.orgapi/cm_api.html#matplotlib.cm.get_cmap). There are also external libraries like
[[palettable]](#palettable) and [[colorcet]](#colorcet) that have many extra colormaps.
Here we briefly discuss how to choose between the many options. For
help on creating your own colormaps, see
[Creating Colormaps in Matplotlib](colormap-manipulation.html).
## Overview
The idea behind choosing a good colormap is to find a good representation in 3D
colorspace for your data set. The best colormap for any given data set depends
on many things including:
- Whether representing form or metric data ([[Ware]](#ware))
- Your knowledge of the data set (*e.g.*, is there a critical value
from which the other values deviate?)
- If there is an intuitive color scheme for the parameter you are plotting
- If there is a standard in the field the audience may be expecting
For many applications, a perceptually uniform colormap is the best
choice --- one in which equal steps in data are perceived as equal
steps in the color space. Researchers have found that the human brain
perceives changes in the lightness parameter as changes in the data
much better than, for example, changes in hue. Therefore, colormaps
which have monotonically increasing lightness through the colormap
will be better interpreted by the viewer. A wonderful example of
perceptually uniform colormaps is [[colorcet]](#colorcet).
Color can be represented in 3D space in various ways. One way to represent color
is using CIELAB. In CIELAB, color space is represented by lightness,
\(L^*\); red-green, \(a^*\); and yellow-blue, \(b^*\). The lightness
parameter \(L^*\) can then be used to learn more about how the matplotlib
colormaps will be perceived by viewers.
An excellent starting resource for learning about human perception of colormaps
is from [[IBM]](#ibm).
## Classes of colormaps
Colormaps are often split into several categories based on their function (see,
*e.g.*, [[Moreland]](#moreland)):
1. Sequential: change in lightness and often saturation of color
incrementally, often using a single hue; should be used for
representing information that has ordering.
1. Diverging: change in lightness and possibly saturation of two
different colors that meet in the middle at an unsaturated color;
should be used when the information being plotted has a critical
middle value, such as topography or when the data deviates around
zero.
1. Cyclic: change in lightness of two different colors that meet in
the middle and beginning/end at an unsaturated color; should be
used for values that wrap around at the endpoints, such as phase
angle, wind direction, or time of day.
1. Qualitative: often are miscellaneous colors; should be used to
represent information which does not have ordering or
relationships.
``` python
# sphinx_gallery_thumbnail_number = 2
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib import cm
from colorspacious import cspace_converter
from collections import OrderedDict
cmaps = OrderedDict()
```
### Sequential
For the Sequential plots, the lightness value increases monotonically through
the colormaps. This is good. Some of the \(L^*\) values in the colormaps
span from 0 to 100 (binary and the other grayscale), and others start around
\(L^*=20\). Those that have a smaller range of \(L^*\) will accordingly
have a smaller perceptual range. Note also that the \(L^*\) function varies
amongst the colormaps: some are approximately linear in \(L^*\) and others
are more curved.
``` python
cmaps['Perceptually Uniform Sequential'] = [
'viridis', 'plasma', 'inferno', 'magma', 'cividis']
cmaps['Sequential'] = [
'Greys', 'Purples', 'Blues', 'Greens', 'Oranges', 'Reds',
'YlOrBr', 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu',
'GnBu', 'PuBu', 'YlGnBu', 'PuBuGn', 'BuGn', 'YlGn']
```
### Sequential2
Many of the \(L^*\) values from the Sequential2 plots are monotonically
increasing, but some (autumn, cool, spring, and winter) plateau or even go both
up and down in \(L^*\) space. Others (afmhot, copper, gist_heat, and hot)
have kinks in the \(L^*\) functions. Data that is being represented in a
region of the colormap that is at a plateau or kink will lead to a perception of
banding of the data in those values in the colormap (see [[mycarta-banding]](#mycarta-banding) for
an excellent example of this).
``` python
cmaps['Sequential (2)'] = [
'binary', 'gist_yarg', 'gist_gray', 'gray', 'bone', 'pink',
'spring', 'summer', 'autumn', 'winter', 'cool', 'Wistia',
'hot', 'afmhot', 'gist_heat', 'copper']
```
### Diverging
For the Diverging maps, we want to have monotonically increasing \(L^*\)
values up to a maximum, which should be close to \(L^*=100\), followed by
monotonically decreasing \(L^*\) values. We are looking for approximately
equal minimum \(L^*\) values at opposite ends of the colormap. By these
measures, BrBG and RdBu are good options. coolwarm is a good option, but it
doesn't span a wide range of \(L^*\) values (see grayscale section below).
``` python
cmaps['Diverging'] = [
'PiYG', 'PRGn', 'BrBG', 'PuOr', 'RdGy', 'RdBu',
'RdYlBu', 'RdYlGn', 'Spectral', 'coolwarm', 'bwr', 'seismic']
```
### Cyclic
For Cyclic maps, we want to start and end on the same color, and meet a
symmetric center point in the middle. \(L^*\) should change monotonically
from start to middle, and inversely from middle to end. It should be symmetric
on the increasing and decreasing side, and only differ in hue. At the ends and
middle, \(L^*\) will reverse direction, which should be smoothed in
\(L^*\) space to reduce artifacts. See [[kovesi-colormaps]](#kovesi-colormaps) for more
information on the design of cyclic maps.
The often-used HSV colormap is included in this set of colormaps, although it
is not symmetric to a center point. Additionally, the \(L^*\) values vary
widely throughout the colormap, making it a poor choice for representing data
for viewers to see perceptually. See an extension on this idea at
[[mycarta-jet]](#mycarta-jet).
``` python
cmaps['Cyclic'] = ['twilight', 'twilight_shifted', 'hsv']
```
### Qualitative
Qualitative colormaps are not aimed at being perceptual maps, but looking at the
lightness parameter can verify that for us. The \(L^*\) values move all over
the place throughout the colormap, and are clearly not monotonically increasing.
These would not be good options for use as perceptual colormaps.
``` python
cmaps['Qualitative'] = ['Pastel1', 'Pastel2', 'Paired', 'Accent',
'Dark2', 'Set1', 'Set2', 'Set3',
'tab10', 'tab20', 'tab20b', 'tab20c']
```
### Miscellaneous
Some of the miscellaneous colormaps have particular uses for which
they have been created. For example, gist_earth, ocean, and terrain
all seem to be created for plotting topography (green/brown) and water
depths (blue) together. We would expect to see a divergence in these
colormaps, then, but multiple kinks may not be ideal, such as in
gist_earth and terrain. CMRmap was created to convert well to
grayscale, though it does appear to have some small kinks in
\(L^*\). cubehelix was created to vary smoothly in both lightness
and hue, but appears to have a small hump in the green hue area.
The often-used jet colormap is included in this set of colormaps. We can see
that the \(L^*\) values vary widely throughout the colormap, making it a
poor choice for representing data for viewers to see perceptually. See an
extension on this idea at [[mycarta-jet]](#mycarta-jet).
``` python
cmaps['Miscellaneous'] = [
'flag', 'prism', 'ocean', 'gist_earth', 'terrain', 'gist_stern',
'gnuplot', 'gnuplot2', 'CMRmap', 'cubehelix', 'brg',
'gist_rainbow', 'rainbow', 'jet', 'nipy_spectral', 'gist_ncar']
```
First, we'll show the range of each colormap. Note that some seem
to change more "quickly" than others.
``` python
nrows = max(len(cmap_list) for cmap_category, cmap_list in cmaps.items())
gradient = np.linspace(0, 1, 256)
gradient = np.vstack((gradient, gradient))
def plot_color_gradients(cmap_category, cmap_list, nrows):
fig, axes = plt.subplots(nrows=nrows)
fig.subplots_adjust(top=0.95, bottom=0.01, left=0.2, right=0.99)
axes[0].set_title(cmap_category + ' colormaps', fontsize=14)
for ax, name in zip(axes, cmap_list):
ax.imshow(gradient, aspect='auto', cmap=plt.get_cmap(name))
pos = list(ax.get_position().bounds)
x_text = pos[0] - 0.01
y_text = pos[1] + pos[3]/2.
fig.text(x_text, y_text, name, va='center', ha='right', fontsize=10)
# Turn off *all* ticks & spines, not just the ones with colormaps.
for ax in axes:
ax.set_axis_off()
for cmap_category, cmap_list in cmaps.items():
plot_color_gradients(cmap_category, cmap_list, nrows)
plt.show()
```
- ![sphx_glr_colormaps_001](https://matplotlib.org/_images/sphx_glr_colormaps_001.png)
- ![sphx_glr_colormaps_002](https://matplotlib.org/_images/sphx_glr_colormaps_002.png)
- ![sphx_glr_colormaps_003](https://matplotlib.org/_images/sphx_glr_colormaps_003.png)
- ![sphx_glr_colormaps_004](https://matplotlib.org/_images/sphx_glr_colormaps_004.png)
- ![sphx_glr_colormaps_005](https://matplotlib.org/_images/sphx_glr_colormaps_005.png)
- ![sphx_glr_colormaps_006](https://matplotlib.org/_images/sphx_glr_colormaps_006.png)
- ![sphx_glr_colormaps_007](https://matplotlib.org/_images/sphx_glr_colormaps_007.png)
## Lightness of matplotlib colormaps
Here we examine the lightness values of the matplotlib colormaps.
Note that some documentation on the colormaps is available
([[list-colormaps]](#list-colormaps)).
``` python
mpl.rcParams.update({'font.size': 12})
# Number of colormap per subplot for particular cmap categories
_DSUBS = {'Perceptually Uniform Sequential': 5, 'Sequential': 6,
'Sequential (2)': 6, 'Diverging': 6, 'Cyclic': 3,
'Qualitative': 4, 'Miscellaneous': 6}
# Spacing between the colormaps of a subplot
_DC = {'Perceptually Uniform Sequential': 1.4, 'Sequential': 0.7,
'Sequential (2)': 1.4, 'Diverging': 1.4, 'Cyclic': 1.4,
'Qualitative': 1.4, 'Miscellaneous': 1.4}
# Indices to step through colormap
x = np.linspace(0.0, 1.0, 100)
# Do plot
for cmap_category, cmap_list in cmaps.items():
# Do subplots so that colormaps have enough space.
# Default is 6 colormaps per subplot.
dsub = _DSUBS.get(cmap_category, 6)
nsubplots = int(np.ceil(len(cmap_list) / dsub))
# squeeze=False to handle similarly the case of a single subplot
fig, axes = plt.subplots(nrows=nsubplots, squeeze=False,
figsize=(7, 2.6*nsubplots))
for i, ax in enumerate(axes.flat):
locs = [] # locations for text labels
for j, cmap in enumerate(cmap_list[i*dsub:(i+1)*dsub]):
# Get RGB values for colormap and convert the colormap in
# CAM02-UCS colorspace. lab[0, :, 0] is the lightness.
rgb = cm.get_cmap(cmap)(x)[np.newaxis, :, :3]
lab = cspace_converter("sRGB1", "CAM02-UCS")(rgb)
# Plot colormap L values. Do separately for each category
# so each plot can be pretty. To make scatter markers change
# color along plot:
# http://stackoverflow.com/questions/8202605/
if cmap_category == 'Sequential':
# These colormaps all start at high lightness but we want them
# reversed to look nice in the plot, so reverse the order.
y_ = lab[0, ::-1, 0]
c_ = x[::-1]
else:
y_ = lab[0, :, 0]
c_ = x
dc = _DC.get(cmap_category, 1.4) # cmaps horizontal spacing
ax.scatter(x + j*dc, y_, c=c_, cmap=cmap, s=300, linewidths=0.0)
# Store locations for colormap labels
if cmap_category in ('Perceptually Uniform Sequential',
'Sequential'):
locs.append(x[-1] + j*dc)
elif cmap_category in ('Diverging', 'Qualitative', 'Cyclic',
'Miscellaneous', 'Sequential (2)'):
locs.append(x[int(x.size/2.)] + j*dc)
# Set up the axis limits:
# * the 1st subplot is used as a reference for the x-axis limits
# * lightness values goes from 0 to 100 (y-axis limits)
ax.set_xlim(axes[0, 0].get_xlim())
ax.set_ylim(0.0, 100.0)
# Set up labels for colormaps
ax.xaxis.set_ticks_position('top')
ticker = mpl.ticker.FixedLocator(locs)
ax.xaxis.set_major_locator(ticker)
formatter = mpl.ticker.FixedFormatter(cmap_list[i*dsub:(i+1)*dsub])
ax.xaxis.set_major_formatter(formatter)
ax.xaxis.set_tick_params(rotation=50)
ax.set_xlabel(cmap_category + ' colormaps', fontsize=14)
fig.text(0.0, 0.55, 'Lightness $L^*$', fontsize=12,
transform=fig.transFigure, rotation=90)
fig.tight_layout(h_pad=0.0, pad=1.5)
plt.show()
```
- ![sphx_glr_colormaps_008](https://matplotlib.org/_images/sphx_glr_colormaps_008.png)
- ![sphx_glr_colormaps_009](https://matplotlib.org/_images/sphx_glr_colormaps_009.png)
- ![sphx_glr_colormaps_010](https://matplotlib.org/_images/sphx_glr_colormaps_010.png)
- ![sphx_glr_colormaps_011](https://matplotlib.org/_images/sphx_glr_colormaps_011.png)
- ![sphx_glr_colormaps_012](https://matplotlib.org/_images/sphx_glr_colormaps_012.png)
- ![sphx_glr_colormaps_013](https://matplotlib.org/_images/sphx_glr_colormaps_013.png)
- ![sphx_glr_colormaps_014](https://matplotlib.org/_images/sphx_glr_colormaps_014.png)
## Grayscale conversion
It is important to pay attention to conversion to grayscale for color
plots, since they may be printed on black and white printers. If not
carefully considered, your readers may end up with indecipherable
plots because the grayscale changes unpredictably through the
colormap.
Conversion to grayscale is done in many different ways [[bw]](#bw). Some of the
better ones use a linear combination of the rgb values of a pixel, but
weighted according to how we perceive color intensity. A nonlinear method of
conversion to grayscale is to use the \(L^*\) values of the pixels. In
general, similar principles apply for this question as they do for presenting
one's information perceptually; that is, if a colormap is chosen that is
monotonically increasing in \(L^*\) values, it will print in a reasonable
manner to grayscale.
With this in mind, we see that the Sequential colormaps have reasonable
representations in grayscale. Some of the Sequential2 colormaps have decent
enough grayscale representations, though some (autumn, spring, summer,
winter) have very little grayscale change. If a colormap like this was used
in a plot and then the plot was printed to grayscale, a lot of the
information may map to the same gray values. The Diverging colormaps mostly
vary from darker gray on the outer edges to white in the middle. Some
(PuOr and seismic) have noticeably darker gray on one side than the other
and therefore are not very symmetric. coolwarm has little range of gray scale
and would print to a more uniform plot, losing a lot of detail. Note that
overlaid, labeled contours could help differentiate between one side of the
colormap vs. the other since color cannot be used once a plot is printed to
grayscale. Many of the Qualitative and Miscellaneous colormaps, such as
Accent, hsv, and jet, change from darker to lighter and back to darker gray
throughout the colormap. This would make it impossible for a viewer to
interpret the information in a plot once it is printed in grayscale.
``` python
mpl.rcParams.update({'font.size': 14})
# Indices to step through colormap.
x = np.linspace(0.0, 1.0, 100)
gradient = np.linspace(0, 1, 256)
gradient = np.vstack((gradient, gradient))
def plot_color_gradients(cmap_category, cmap_list):
fig, axes = plt.subplots(nrows=len(cmap_list), ncols=2)
fig.subplots_adjust(top=0.95, bottom=0.01, left=0.2, right=0.99,
wspace=0.05)
fig.suptitle(cmap_category + ' colormaps', fontsize=14, y=1.0, x=0.6)
for ax, name in zip(axes, cmap_list):
# Get RGB values for colormap.
rgb = cm.get_cmap(plt.get_cmap(name))(x)[np.newaxis, :, :3]
# Get colormap in CAM02-UCS colorspace. We want the lightness.
lab = cspace_converter("sRGB1", "CAM02-UCS")(rgb)
L = lab[0, :, 0]
L = np.float32(np.vstack((L, L, L)))
ax[0].imshow(gradient, aspect='auto', cmap=plt.get_cmap(name))
ax[1].imshow(L, aspect='auto', cmap='binary_r', vmin=0., vmax=100.)
pos = list(ax[0].get_position().bounds)
x_text = pos[0] - 0.01
y_text = pos[1] + pos[3]/2.
fig.text(x_text, y_text, name, va='center', ha='right', fontsize=10)
# Turn off *all* ticks & spines, not just the ones with colormaps.
for ax in axes.flat:
ax.set_axis_off()
plt.show()
for cmap_category, cmap_list in cmaps.items():
plot_color_gradients(cmap_category, cmap_list)
```
- ![sphx_glr_colormaps_015](https://matplotlib.org/_images/sphx_glr_colormaps_015.png)
- ![sphx_glr_colormaps_016](https://matplotlib.org/_images/sphx_glr_colormaps_016.png)
- ![sphx_glr_colormaps_017](https://matplotlib.org/_images/sphx_glr_colormaps_017.png)
- ![sphx_glr_colormaps_018](https://matplotlib.org/_images/sphx_glr_colormaps_018.png)
- ![sphx_glr_colormaps_019](https://matplotlib.org/_images/sphx_glr_colormaps_019.png)
- ![sphx_glr_colormaps_020](https://matplotlib.org/_images/sphx_glr_colormaps_020.png)
- ![sphx_glr_colormaps_021](https://matplotlib.org/_images/sphx_glr_colormaps_021.png)
## Color vision deficiencies
There is a lot of information available about color blindness (*e.g.*,
[[colorblindness]](#colorblindness)). Additionally, there are tools available to convert images
to how they look for different types of color vision deficiencies.
The most common form of color vision deficiency involves differentiating
between red and green. Thus, avoiding colormaps with both red and green will
avoid many problems in general.
## References
---
[colorcet]([1](#id[2](#id4)), 2) [https://colorcet.pyviz.org](https://colorcet.pyviz.org)
---
[[Ware]](#id3)[http://ccom.unh.edu/sites/default/files/publications/Ware_1988_CGA_Color_sequences_univariate_maps.pdf](http://ccom.unh.edu/sites/default/files/publications/Ware_1988_CGA_Color_sequences_univariate_maps.pdf)
---
[[Moreland]](#id6)[http://www.kennethmoreland.com/color-maps/ColorMapsExpanded.pdf](http://www.kennethmoreland.com/color-maps/ColorMapsExpanded.pdf)
---
[[list-colormaps]](#id11)[https://gist.github.com/endolith/2719900#id7](https://gist.github.com/endolith/2719900#id7)
---
[[mycarta-banding]](#id7)[https://mycarta.wordpress.com/2012/10/14/the-rainbow-is-deadlong-live-the-rainbow-part-4-cie-lab-heated-body/](https://mycarta.wordpress.com/2012/10/14/the-rainbow-is-deadlong-live-the-rainbow-part-4-cie-lab-heated-body/)
---
[mycarta-jet]([1](#id9), [2](#id10)) [https://mycarta.wordpress.com/2012/10/06/the-rainbow-is-deadlong-live-the-rainbow-part-3/](https://mycarta.wordpress.com/2012/10/06/the-rainbow-is-deadlong-live-the-rainbow-part-3/)
---
[[kovesi-colormaps]](#id8)[https://arxiv.org/abs/1509.03700](https://arxiv.org/abs/1509.03700)
---
[[bw]](#id12)[http://www.tannerhelland.com/3643/grayscale-image-algorithm-vb6/](http://www.tannerhelland.com/3643/grayscale-image-algorithm-vb6/)
---
[[colorblindness]](#id13)[http://www.color-blindness.com/](http://www.color-blindness.com/)
---
[[IBM]](#id5)[https://doi.org/10.1109/VISUAL.1995.480803](https://doi.org/10.1109/VISUAL.1995.480803)
---
[[palettable]](#id1)[https://jiffyclub.github.io/palettable/](https://jiffyclub.github.io/palettable/)
**Total running time of the script:** ( 0 minutes 9.320 seconds)
## Download
- [Download Python source code: colormaps.py](https://matplotlib.org/_downloads/9df0748eeda573fbccab51a7272f7d81/colormaps.py)
- [Download Jupyter notebook: colormaps.ipynb](https://matplotlib.org/_downloads/6024d841c77bf197ffe5612254186669/colormaps.ipynb)

View File

@@ -0,0 +1,135 @@
---
sidebarDepth: 3
sidebar: auto
---
# Specifying Colors
Matplotlib recognizes the following formats to specify a color:
- an RGB or RGBA (red, green, blue, alpha) tuple of float values in ``[0, 1]``
(e.g., ``(0.1, 0.2, 0.5)`` or ``(0.1, 0.2, 0.5, 0.3)``);
- a hex RGB or RGBA string (e.g., ``'#0f0f0f'`` or ``'#0f0f0f80'``;
case-insensitive);
- a string representation of a float value in ``[0, 1]`` inclusive for gray
level (e.g., ``'0.5'``);
- one of ``{'b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'}``;
- a X11/CSS4 color name (case-insensitive);
- a name from the [xkcd color survey](https://xkcd.com/color/rgb/), prefixed with ``'xkcd:'`` (e.g.,
``'xkcd:sky blue'``; case insensitive);
- one of the Tableau Colors from the 'T10' categorical palette (the default
color cycle): ``{'tab:blue', 'tab:orange', 'tab:green', 'tab:red',
'tab:purple', 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan'}``
(case-insensitive);
- a "CN" color spec, i.e. ``'C'`` followed by a number, which is an index into
the default property cycle (``matplotlib.rcParams['axes.prop_cycle']``); the
indexing is intended to occur at rendering time, and defaults to black if the
cycle does not include color.
"Red", "Green", and "Blue" are the intensities of those colors, the combination
of which span the colorspace.
How "Alpha" behaves depends on the ``zorder`` of the Artist. Higher
``zorder`` Artists are drawn on top of lower Artists, and "Alpha" determines
whether the lower artist is covered by the higher.
If the old RGB of a pixel is ``RGBold`` and the RGB of the
pixel of the Artist being added is ``RGBnew`` with Alpha ``alpha``,
then the RGB of the pixel is updated to:
``RGB = RGBOld * (1 - Alpha) + RGBnew * Alpha``. Alpha
of 1 means the old color is completely covered by the new Artist, Alpha of 0
means that pixel of the Artist is transparent.
For more information on colors in matplotlib see
- the [Color Demo](https://matplotlib.orggallery/color/color_demo.html) example;
- the [``matplotlib.colors``](https://matplotlib.orgapi/colors_api.html#module-matplotlib.colors) API;
- the [List of named colors](https://matplotlib.orggallery/color/named_colors.html) example.
## "CN" color selection
"CN" colors are converted to RGBA as soon as the artist is created. For
example,
``` python
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
th = np.linspace(0, 2*np.pi, 128)
def demo(sty):
mpl.style.use(sty)
fig, ax = plt.subplots(figsize=(3, 3))
ax.set_title('style: {!r}'.format(sty), color='C0')
ax.plot(th, np.cos(th), 'C1', label='C1')
ax.plot(th, np.sin(th), 'C2', label='C2')
ax.legend()
demo('default')
demo('seaborn')
```
- ![sphx_glr_colors_001](https://matplotlib.org/_images/sphx_glr_colors_001.png)
- ![sphx_glr_colors_002](https://matplotlib.org/_images/sphx_glr_colors_002.png)
will use the first color for the title and then plot using the second
and third colors of each style's ``mpl.rcParams['axes.prop_cycle']``.
## xkcd v X11/CSS4
The xkcd colors are derived from a user survey conducted by the
webcomic xkcd. [Details of the survey are available on the xkcd blog](https://blog.xkcd.com/2010/05/03/color-survey-results/).
Out of 148 colors in the CSS color list, there are 95 name collisions
between the X11/CSS4 names and the xkcd names, all but 3 of which have
different hex values. For example ``'blue'`` maps to ``'#0000FF'``
where as ``'xkcd:blue'`` maps to ``'#0343DF'``. Due to these name
collisions all of the xkcd colors have ``'xkcd:'`` prefixed. As noted in
the blog post, while it might be interesting to re-define the X11/CSS4 names
based on such a survey, we do not do so unilaterally.
The name collisions are shown in the table below; the color names
where the hex values agree are shown in bold.
``` python
import matplotlib._color_data as mcd
import matplotlib.patches as mpatch
overlap = {name for name in mcd.CSS4_COLORS
if "xkcd:" + name in mcd.XKCD_COLORS}
fig = plt.figure(figsize=[4.8, 16])
ax = fig.add_axes([0, 0, 1, 1])
for j, n in enumerate(sorted(overlap, reverse=True)):
weight = None
cn = mcd.CSS4_COLORS[n]
xkcd = mcd.XKCD_COLORS["xkcd:" + n].upper()
if cn == xkcd:
weight = 'bold'
r1 = mpatch.Rectangle((0, j), 1, 1, color=cn)
r2 = mpatch.Rectangle((1, j), 1, 1, color=xkcd)
txt = ax.text(2, j+.5, ' ' + n, va='center', fontsize=10,
weight=weight)
ax.add_patch(r1)
ax.add_patch(r2)
ax.axhline(j, color='k')
ax.text(.5, j + 1.5, 'X11', ha='center', va='center')
ax.text(1.5, j + 1.5, 'xkcd', ha='center', va='center')
ax.set_xlim(0, 3)
ax.set_ylim(0, j + 2)
ax.axis('off')
```
![sphx_glr_colors_003](https://matplotlib.org/_images/sphx_glr_colors_003.png)
## Download
- [Download Python source code: colors.py](https://matplotlib.org/_downloads/8fb6dfde0db5f6422a7627d0d4e328b2/colors.py)
- [Download Jupyter notebook: colors.ipynb](https://matplotlib.org/_downloads/04907c28d4180c02e547778b9aaee05d/colors.ipynb)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
# 衰变
这个例子展示了:
- 使用生成器来驱动动画,
- 在动画期间更改轴限制。
![衰变示例](https://matplotlib.org/_images/sphx_glr_animate_decay_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
def data_gen(t=0):
cnt = 0
while cnt < 1000:
cnt += 1
t += 0.1
yield t, np.sin(2*np.pi*t) * np.exp(-t/10.)
def init():
ax.set_ylim(-1.1, 1.1)
ax.set_xlim(0, 10)
del xdata[:]
del ydata[:]
line.set_data(xdata, ydata)
return line,
fig, ax = plt.subplots()
line, = ax.plot([], [], lw=2)
ax.grid()
xdata, ydata = [], []
def run(data):
# update the data
t, y = data
xdata.append(t)
ydata.append(y)
xmin, xmax = ax.get_xlim()
if t >= xmax:
ax.set_xlim(xmin, 2*xmax)
ax.figure.canvas.draw()
line.set_data(xdata, ydata)
return line,
ani = animation.FuncAnimation(fig, run, data_gen, blit=False, interval=10,
repeat=False, init_func=init)
plt.show()
```
## 下载这个示例
- [下载python源码: animate_decay.py](https://matplotlib.org/_downloads/animate_decay.py)
- [下载Jupyter notebook: animate_decay.ipynb](https://matplotlib.org/_downloads/animate_decay.ipynb)

View File

@@ -0,0 +1,89 @@
# 动画直方图
使用路径补丁为动画直方图绘制一堆矩形。
```python
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib.path as path
import matplotlib.animation as animation
# Fixing random state for reproducibility
np.random.seed(19680801)
# histogram our data with numpy
data = np.random.randn(1000)
n, bins = np.histogram(data, 100)
# get the corners of the rectangles for the histogram
left = np.array(bins[:-1])
right = np.array(bins[1:])
bottom = np.zeros(len(left))
top = bottom + n
nrects = len(left)
```
这里有一个棘手的部分 - 我们必须为每个rect使用 ``plt.Path.MOVETO````plt.Path.LINETO``和``plt.Path.CLOSEPOLY``设置顶点和路径代码数组。
- 每个矩形我们需要1个 ``MOVETO``,它设置了初始点。
- 我们需要3个``LINETO``它告诉Matplotlib从顶点1到顶点2v2到v3和v3到v4绘制线。
- 然后我们需要一个``CLOSEPOLY``它告诉Matplotlib从v4到我们的初始顶点MOVETO顶点绘制一条线以便关闭多边形。
**注意:**CLOSEPOLY的顶点被忽略但我们仍然需要在verts数组中使用占位符来保持代码与顶点对齐。
```python
nverts = nrects * (1 + 3 + 1)
verts = np.zeros((nverts, 2))
codes = np.ones(nverts, int) * path.Path.LINETO
codes[0::5] = path.Path.MOVETO
codes[4::5] = path.Path.CLOSEPOLY
verts[0::5, 0] = left
verts[0::5, 1] = bottom
verts[1::5, 0] = left
verts[1::5, 1] = top
verts[2::5, 0] = right
verts[2::5, 1] = top
verts[3::5, 0] = right
verts[3::5, 1] = bottom
```
为了给直方图设置动画,我们需要一个动画函数,它生成一组随机数字并更新直方图顶点的位置(在这种情况下,只有每个矩形的高度)。 补丁最终将成为补丁对象。
```python
patch = None
def animate(i):
# simulate new data coming in
data = np.random.randn(1000)
n, bins = np.histogram(data, 100)
top = bottom + n
verts[1::5, 1] = top
verts[2::5, 1] = top
return [patch, ]
```
现在我们使用顶点和代码为直方图构建Path和Patch实例。 我们将补丁添加到Axes实例并使用我们的animate函数设置``FuncAnimation``。
```python
fig, ax = plt.subplots()
barpath = path.Path(verts, codes)
patch = patches.PathPatch(
barpath, facecolor='green', edgecolor='yellow', alpha=0.5)
ax.add_patch(patch)
ax.set_xlim(left[0], right[-1])
ax.set_ylim(bottom.min(), top.max())
ani = animation.FuncAnimation(fig, animate, 100, repeat=False, blit=True)
plt.show()
```
![动画直方图示例](https://matplotlib.org/_images/sphx_glr_animated_histogram_001.png)
## 下载这个示例
- [下载python源码: animated_histogram.py](https://matplotlib.org/_downloads/animated_histogram.py)
- [下载Jupyter notebook: animated_histogram.ipynb](https://matplotlib.org/_downloads/animated_histogram.ipynb)

View File

@@ -0,0 +1,33 @@
# pyplot动画
通过调用绘图命令之间的[暂停](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.pause.html#matplotlib.pyplot.pause)来生成动画。
此处显示的方法仅适用于简单,低性能的使用。 对于要求更高的应用程序,请查看``动画模块``和使用它的示例。
请注意,调用[time.sleep](https://docs.python.org/3/library/time.html#time.sleep)而不是[暂停](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.pause.html#matplotlib.pyplot.pause)将不起作用。
![pyplot动画](https://matplotlib.org/_images/sphx_glr_animation_demo_001.png)
```python
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(19680801)
data = np.random.random((50, 50, 50))
fig, ax = plt.subplots()
for i in range(len(data)):
ax.cla()
ax.imshow(data[i])
ax.set_title("frame {}".format(i))
# Note that using time.sleep does *not* work here!
plt.pause(0.1)
```
**脚本总运行时间:**0分7.211秒)
## 下载这个示例
- [下载python源码: animation_demo.py](https://matplotlib.org/_downloads/animation_demo.py)
- [下载Jupyter notebook: animation_demo.ipynb](https://matplotlib.org/_downloads/animation_demo.ipynb)

View File

@@ -0,0 +1,71 @@
# 贝叶斯更新
此动画显示在新数据到达时重新安装的后验估计更新。
垂直线表示绘制的分布应该收敛的理论值。
![贝叶斯更新示例](https://matplotlib.org/_images/sphx_glr_bayes_update_001.png)
```python
import math
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def beta_pdf(x, a, b):
return (x**(a-1) * (1-x)**(b-1) * math.gamma(a + b)
/ (math.gamma(a) * math.gamma(b)))
class UpdateDist(object):
def __init__(self, ax, prob=0.5):
self.success = 0
self.prob = prob
self.line, = ax.plot([], [], 'k-')
self.x = np.linspace(0, 1, 200)
self.ax = ax
# Set up plot parameters
self.ax.set_xlim(0, 1)
self.ax.set_ylim(0, 15)
self.ax.grid(True)
# This vertical line represents the theoretical value, to
# which the plotted distribution should converge.
self.ax.axvline(prob, linestyle='--', color='black')
def init(self):
self.success = 0
self.line.set_data([], [])
return self.line,
def __call__(self, i):
# This way the plot can continuously run and we just keep
# watching new realizations of the process
if i == 0:
return self.init()
# Choose success based on exceed a threshold with a uniform pick
if np.random.rand(1,) < self.prob:
self.success += 1
y = beta_pdf(self.x, self.success + 1, (i - self.success) + 1)
self.line.set_data(self.x, y)
return self.line,
# Fixing random state for reproducibility
np.random.seed(19680801)
fig, ax = plt.subplots()
ud = UpdateDist(ax, prob=0.7)
anim = FuncAnimation(fig, ud, frames=np.arange(100), init_func=ud.init,
interval=100, blit=True)
plt.show()
```
## 下载这个示例
- [下载python源码: bayes_update.py](https://matplotlib.org/_downloads/bayes_update.py)
- [下载Jupyter notebook: bayes_update.ipynb](https://matplotlib.org/_downloads/bayes_update.ipynb)

View File

@@ -0,0 +1,99 @@
# 双摆问题
这个动画说明了双摆问题。
双摆公式从 http://www.physics.usyd.edu.au/~wheat/dpend_html/solve_dpend.c 的C代码翻译而来。
```python
from numpy import sin, cos
import numpy as np
import matplotlib.pyplot as plt
import scipy.integrate as integrate
import matplotlib.animation as animation
G = 9.8 # acceleration due to gravity, in m/s^2
L1 = 1.0 # length of pendulum 1 in m
L2 = 1.0 # length of pendulum 2 in m
M1 = 1.0 # mass of pendulum 1 in kg
M2 = 1.0 # mass of pendulum 2 in kg
def derivs(state, t):
dydx = np.zeros_like(state)
dydx[0] = state[1]
del_ = state[2] - state[0]
den1 = (M1 + M2)*L1 - M2*L1*cos(del_)*cos(del_)
dydx[1] = (M2*L1*state[1]*state[1]*sin(del_)*cos(del_) +
M2*G*sin(state[2])*cos(del_) +
M2*L2*state[3]*state[3]*sin(del_) -
(M1 + M2)*G*sin(state[0]))/den1
dydx[2] = state[3]
den2 = (L2/L1)*den1
dydx[3] = (-M2*L2*state[3]*state[3]*sin(del_)*cos(del_) +
(M1 + M2)*G*sin(state[0])*cos(del_) -
(M1 + M2)*L1*state[1]*state[1]*sin(del_) -
(M1 + M2)*G*sin(state[2]))/den2
return dydx
# create a time array from 0..100 sampled at 0.05 second steps
dt = 0.05
t = np.arange(0.0, 20, dt)
# th1 and th2 are the initial angles (degrees)
# w10 and w20 are the initial angular velocities (degrees per second)
th1 = 120.0
w1 = 0.0
th2 = -10.0
w2 = 0.0
# initial state
state = np.radians([th1, w1, th2, w2])
# integrate your ODE using scipy.integrate.
y = integrate.odeint(derivs, state, t)
x1 = L1*sin(y[:, 0])
y1 = -L1*cos(y[:, 0])
x2 = L2*sin(y[:, 2]) + x1
y2 = -L2*cos(y[:, 2]) + y1
fig = plt.figure()
ax = fig.add_subplot(111, autoscale_on=False, xlim=(-2, 2), ylim=(-2, 2))
ax.set_aspect('equal')
ax.grid()
line, = ax.plot([], [], 'o-', lw=2)
time_template = 'time = %.1fs'
time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes)
def init():
line.set_data([], [])
time_text.set_text('')
return line, time_text
def animate(i):
thisx = [0, x1[i], x2[i]]
thisy = [0, y1[i], y2[i]]
line.set_data(thisx, thisy)
time_text.set_text(time_template % (i*dt))
return line, time_text
ani = animation.FuncAnimation(fig, animate, np.arange(1, len(y)),
interval=25, blit=True, init_func=init)
plt.show()
```
## 下载这个示例
- [下载python源码: double_pendulum_sgskip.py](https://matplotlib.org/_downloads/double_pendulum_sgskip.py)
- [下载Jupyter notebook: double_pendulum_sgskip.ipynb](https://matplotlib.org/_downloads/double_pendulum_sgskip.ipynb)

View File

@@ -0,0 +1,47 @@
# 使用预先计算的图像列表的动画图像
![使用预先计算的图像列表的动画图像示例](https://matplotlib.org/_images/sphx_glr_dynamic_image_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig = plt.figure()
def f(x, y):
return np.sin(x) + np.cos(y)
x = np.linspace(0, 2 * np.pi, 120)
y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
# ims is a list of lists, each row is a list of artists to draw in the
# current frame; here we are just animating one artist, the image, in
# each frame
ims = []
for i in range(60):
x += np.pi / 15.
y += np.pi / 20.
im = plt.imshow(f(x, y), animated=True)
ims.append([im])
ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True,
repeat_delay=1000)
# To save the animation, use e.g.
#
# ani.save("movie.mp4")
#
# or
#
# from matplotlib.animation import FFMpegWriter
# writer = FFMpegWriter(fps=15, metadata=dict(artist='Me'), bitrate=1800)
# ani.save("movie.mp4", writer=writer)
plt.show()
```
## 下载这个示例
- [下载python源码: dynamic_image.py](https://matplotlib.org/_downloads/dynamic_image.py)
- [下载Jupyter notebook: dynamic_image.ipynb](https://matplotlib.org/_downloads/dynamic_image.ipynb)

View File

@@ -0,0 +1,39 @@
# 帧抓取
直接使用MovieWriter抓取单个帧并将其写入文件。 这避免了任何事件循环集成因此甚至可以与Agg后端一起使用。 建议不要在交互式设置中使用。
```python
import numpy as np
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib.animation import FFMpegWriter
# Fixing random state for reproducibility
np.random.seed(19680801)
metadata = dict(title='Movie Test', artist='Matplotlib',
comment='Movie support!')
writer = FFMpegWriter(fps=15, metadata=metadata)
fig = plt.figure()
l, = plt.plot([], [], 'k-o')
plt.xlim(-5, 5)
plt.ylim(-5, 5)
x0, y0 = 0, 0
with writer.saving(fig, "writer_test.mp4", 100):
for i in range(100):
x0 += 0.1 * np.random.randn()
y0 += 0.1 * np.random.randn()
l.set_data(x0, y0)
writer.grab_frame()
```
## 下载这个示例
- [下载python源码: frame_grabbing_sgskip.py](https://matplotlib.org/_downloads/frame_grabbing_sgskip.py)
- [下载Jupyter notebook: frame_grabbing_sgskip.ipynb](https://matplotlib.org/_downloads/frame_grabbing_sgskip.ipynb)

View File

@@ -0,0 +1,75 @@
# 雨模拟
通过设置50个散点的比例和不透明度来模拟表面上的雨滴。
作者Nicolas P. Rougier
![雨模拟示例](https://matplotlib.org/_images/sphx_glr_rain_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
# Fixing random state for reproducibility
np.random.seed(19680801)
# Create new Figure and an Axes which fills it.
fig = plt.figure(figsize=(7, 7))
ax = fig.add_axes([0, 0, 1, 1], frameon=False)
ax.set_xlim(0, 1), ax.set_xticks([])
ax.set_ylim(0, 1), ax.set_yticks([])
# Create rain data
n_drops = 50
rain_drops = np.zeros(n_drops, dtype=[('position', float, 2),
('size', float, 1),
('growth', float, 1),
('color', float, 4)])
# Initialize the raindrops in random positions and with
# random growth rates.
rain_drops['position'] = np.random.uniform(0, 1, (n_drops, 2))
rain_drops['growth'] = np.random.uniform(50, 200, n_drops)
# Construct the scatter which we will update during animation
# as the raindrops develop.
scat = ax.scatter(rain_drops['position'][:, 0], rain_drops['position'][:, 1],
s=rain_drops['size'], lw=0.5, edgecolors=rain_drops['color'],
facecolors='none')
def update(frame_number):
# Get an index which we can use to re-spawn the oldest raindrop.
current_index = frame_number % n_drops
# Make all colors more transparent as time progresses.
rain_drops['color'][:, 3] -= 1.0/len(rain_drops)
rain_drops['color'][:, 3] = np.clip(rain_drops['color'][:, 3], 0, 1)
# Make all circles bigger.
rain_drops['size'] += rain_drops['growth']
# Pick a new position for oldest rain drop, resetting its size,
# color and growth factor.
rain_drops['position'][current_index] = np.random.uniform(0, 1, 2)
rain_drops['size'][current_index] = 5
rain_drops['color'][current_index] = (0, 0, 0, 1)
rain_drops['growth'][current_index] = np.random.uniform(50, 200)
# Update the scatter collection, with the new colors, sizes and positions.
scat.set_edgecolors(rain_drops['color'])
scat.set_sizes(rain_drops['size'])
scat.set_offsets(rain_drops['position'])
# Construct the animation, using the update function as the animation director.
animation = FuncAnimation(fig, update, interval=10)
plt.show()
```
## 下载这个示例
- [下载python源码: rain.py](https://matplotlib.org/_downloads/rain.py)
- [下载Jupyter notebook: rain.ipynb](https://matplotlib.org/_downloads/rain.ipynb)

View File

@@ -0,0 +1,75 @@
# 动画3D随机游走
![动画3D随机游走](https://matplotlib.org/_images/sphx_glr_random_walk_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib.animation as animation
# Fixing random state for reproducibility
np.random.seed(19680801)
def Gen_RandLine(length, dims=2):
"""
Create a line using a random walk algorithm
length is the number of points for the line.
dims is the number of dimensions the line has.
"""
lineData = np.empty((dims, length))
lineData[:, 0] = np.random.rand(dims)
for index in range(1, length):
# scaling the random numbers by 0.1 so
# movement is small compared to position.
# subtraction by 0.5 is to change the range to [-0.5, 0.5]
# to allow a line to move backwards.
step = ((np.random.rand(dims) - 0.5) * 0.1)
lineData[:, index] = lineData[:, index - 1] + step
return lineData
def update_lines(num, dataLines, lines):
for line, data in zip(lines, dataLines):
# NOTE: there is no .set_data() for 3 dim data...
line.set_data(data[0:2, :num])
line.set_3d_properties(data[2, :num])
return lines
# Attaching 3D axis to the figure
fig = plt.figure()
ax = p3.Axes3D(fig)
# Fifty lines of random 3-D lines
data = [Gen_RandLine(25, 3) for index in range(50)]
# Creating fifty line objects.
# NOTE: Can't pass empty arrays into 3d version of plot()
lines = [ax.plot(dat[0, 0:1], dat[1, 0:1], dat[2, 0:1])[0] for dat in data]
# Setting the axes properties
ax.set_xlim3d([0.0, 1.0])
ax.set_xlabel('X')
ax.set_ylim3d([0.0, 1.0])
ax.set_ylabel('Y')
ax.set_zlim3d([0.0, 1.0])
ax.set_zlabel('Z')
ax.set_title('3D Test')
# Creating the Animation object
line_ani = animation.FuncAnimation(fig, update_lines, 25, fargs=(data, lines),
interval=50, blit=False)
plt.show()
```
## 下载这个示例
- [下载python源码: random_walk.py](https://matplotlib.org/_downloads/random_walk.py)
- [下载Jupyter notebook: random_walk.ipynb](https://matplotlib.org/_downloads/random_walk.ipynb)

View File

@@ -0,0 +1,45 @@
# 动画线图
![动画线图](https://matplotlib.org/_images/sphx_glr_simple_anim_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots()
x = np.arange(0, 2*np.pi, 0.01)
line, = ax.plot(x, np.sin(x))
def init(): # only required for blitting to give a clean slate.
line.set_ydata([np.nan] * len(x))
return line,
def animate(i):
line.set_ydata(np.sin(x + i / 100)) # update the data.
return line,
ani = animation.FuncAnimation(
fig, animate, init_func=init, interval=2, blit=True, save_count=50)
# To save the animation, use e.g.
#
# ani.save("movie.mp4")
#
# or
#
# from matplotlib.animation import FFMpegWriter
# writer = FFMpegWriter(fps=15, metadata=dict(artist='Me'), bitrate=1800)
# ani.save("movie.mp4", writer=writer)
plt.show()
```
## 下载这个示例
- [下载python源码: simple_anim.py](https://matplotlib.org/_downloads/simple_anim.py)
- [下载Jupyter notebook: simple_anim.ipynb](https://matplotlib.org/_downloads/simple_anim.ipynb)

View File

@@ -0,0 +1,67 @@
# 示波器
模拟示波器。
![示波器示例](https://matplotlib.org/_images/sphx_glr_strip_chart_001.png)
```python
import numpy as np
from matplotlib.lines import Line2D
import matplotlib.pyplot as plt
import matplotlib.animation as animation
class Scope(object):
def __init__(self, ax, maxt=2, dt=0.02):
self.ax = ax
self.dt = dt
self.maxt = maxt
self.tdata = [0]
self.ydata = [0]
self.line = Line2D(self.tdata, self.ydata)
self.ax.add_line(self.line)
self.ax.set_ylim(-.1, 1.1)
self.ax.set_xlim(0, self.maxt)
def update(self, y):
lastt = self.tdata[-1]
if lastt > self.tdata[0] + self.maxt: # reset the arrays
self.tdata = [self.tdata[-1]]
self.ydata = [self.ydata[-1]]
self.ax.set_xlim(self.tdata[0], self.tdata[0] + self.maxt)
self.ax.figure.canvas.draw()
t = self.tdata[-1] + self.dt
self.tdata.append(t)
self.ydata.append(y)
self.line.set_data(self.tdata, self.ydata)
return self.line,
def emitter(p=0.03):
'return a random value with probability p, else 0'
while True:
v = np.random.rand(1)
if v > p:
yield 0.
else:
yield np.random.rand(1)
# Fixing random state for reproducibility
np.random.seed(19680801)
fig, ax = plt.subplots()
scope = Scope(ax)
# pass a generator in "emitter" to produce data for the update func
ani = animation.FuncAnimation(fig, scope.update, emitter, interval=10,
blit=True)
plt.show()
```
## 下载这个示例
- [下载python源码: strip_chart.py](https://matplotlib.org/_downloads/strip_chart.py)
- [下载Jupyter notebook: strip_chart.ipynb](https://matplotlib.org/_downloads/strip_chart.ipynb)

View File

@@ -0,0 +1,77 @@
# MATPLOTLIB UNCHAINED
脉冲星的假信号频率的比较路径演示主要是因为Joy Division的未知乐趣的封面而闻名
作者Nicolas P. Rougier
![MATPLOTLIB UNCHAINED示例](https://matplotlib.org/_images/sphx_glr_unchained_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
# Fixing random state for reproducibility
np.random.seed(19680801)
# Create new Figure with black background
fig = plt.figure(figsize=(8, 8), facecolor='black')
# Add a subplot with no frame
ax = plt.subplot(111, frameon=False)
# Generate random data
data = np.random.uniform(0, 1, (64, 75))
X = np.linspace(-1, 1, data.shape[-1])
G = 1.5 * np.exp(-4 * X ** 2)
# Generate line plots
lines = []
for i in range(len(data)):
# Small reduction of the X extents to get a cheap perspective effect
xscale = 1 - i / 200.
# Same for linewidth (thicker strokes on bottom)
lw = 1.5 - i / 100.0
line, = ax.plot(xscale * X, i + G * data[i], color="w", lw=lw)
lines.append(line)
# Set y limit (or first line is cropped because of thickness)
ax.set_ylim(-1, 70)
# No ticks
ax.set_xticks([])
ax.set_yticks([])
# 2 part titles to get different font weights
ax.text(0.5, 1.0, "MATPLOTLIB ", transform=ax.transAxes,
ha="right", va="bottom", color="w",
family="sans-serif", fontweight="light", fontsize=16)
ax.text(0.5, 1.0, "UNCHAINED", transform=ax.transAxes,
ha="left", va="bottom", color="w",
family="sans-serif", fontweight="bold", fontsize=16)
def update(*args):
# Shift all data to the right
data[:, 1:] = data[:, :-1]
# Fill-in new values
data[:, 0] = np.random.uniform(0, 1, len(data))
# Update data
for i in range(len(data)):
lines[i].set_ydata(i + G * data[i])
# Return modified artists
return lines
# Construct the animation, using the update function as the animation director.
anim = animation.FuncAnimation(fig, update, interval=10)
plt.show()
```
## 下载这个示例
- [下载python源码: unchained.py](https://matplotlib.org/_downloads/unchained.py)
- [下载Jupyter notebook: unchained.ipynb](https://matplotlib.org/_downloads/unchained.ipynb)

View File

@@ -0,0 +1,83 @@
# 演示锚定方向箭头
![演示锚定方向箭头示例](https://matplotlib.org/_images/sphx_glr_demo_anchored_direction_arrows_001.png)
```python
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredDirectionArrows
import matplotlib.font_manager as fm
fig, ax = plt.subplots()
ax.imshow(np.random.random((10, 10)))
# Simple example
simple_arrow = AnchoredDirectionArrows(ax.transAxes, 'X', 'Y')
ax.add_artist(simple_arrow)
# High contrast arrow
high_contrast_part_1 = AnchoredDirectionArrows(
ax.transAxes,
'111', r'11$\overline{2}$',
loc='upper right',
arrow_props={'ec': 'w', 'fc': 'none', 'alpha': 1,
'lw': 2}
)
ax.add_artist(high_contrast_part_1)
high_contrast_part_2 = AnchoredDirectionArrows(
ax.transAxes,
'111', r'11$\overline{2}$',
loc='upper right',
arrow_props={'ec': 'none', 'fc': 'k'},
text_props={'ec': 'w', 'fc': 'k', 'lw': 0.4}
)
ax.add_artist(high_contrast_part_2)
# Rotated arrow
fontprops = fm.FontProperties(family='serif')
roatated_arrow = AnchoredDirectionArrows(
ax.transAxes,
'30', '120',
loc='center',
color='w',
angle=30,
fontproperties=fontprops
)
ax.add_artist(roatated_arrow)
# Altering arrow directions
a1 = AnchoredDirectionArrows(
ax.transAxes, 'A', 'B', loc='lower center',
length=-0.15,
sep_x=0.03, sep_y=0.03,
color='r'
)
ax.add_artist(a1)
a2 = AnchoredDirectionArrows(
ax.transAxes, 'A', ' B', loc='lower left',
aspect_ratio=-1,
sep_x=0.01, sep_y=-0.02,
color='orange'
)
ax.add_artist(a2)
a3 = AnchoredDirectionArrows(
ax.transAxes, ' A', 'B', loc='lower right',
length=-0.15,
aspect_ratio=-1,
sep_y=-0.1, sep_x=0.04,
color='cyan'
)
ax.add_artist(a3)
plt.show()
```
## 下载这个示例
- [下载python源码: demo_anchored_direction_arrows.py](https://matplotlib.org/_downloads/demo_anchored_direction_arrows.py)
- [下载Jupyter notebook: demo_anchored_direction_arrows.ipynb](https://matplotlib.org/_downloads/demo_anchored_direction_arrows.ipynb)

View File

@@ -0,0 +1,137 @@
# 演示Axes Divider
轴分割器用于计算轴的位置,并使用现有轴实例为它们创建分隔线。
![演示Axes Divider示例](https://matplotlib.org/_images/sphx_glr_demo_axes_divider_001.png)
```python
import matplotlib.pyplot as plt
def get_demo_image():
import numpy as np
from matplotlib.cbook import get_sample_data
f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False)
z = np.load(f)
# z is a numpy array of 15x15
return z, (-3, 4, -4, 3)
def demo_simple_image(ax):
Z, extent = get_demo_image()
im = ax.imshow(Z, extent=extent, interpolation="nearest")
cb = plt.colorbar(im)
plt.setp(cb.ax.get_yticklabels(), visible=False)
def demo_locatable_axes_hard(fig1):
from mpl_toolkits.axes_grid1 import SubplotDivider, Size
from mpl_toolkits.axes_grid1.mpl_axes import Axes
divider = SubplotDivider(fig1, 2, 2, 2, aspect=True)
# axes for image
ax = Axes(fig1, divider.get_position())
# axes for colorbar
ax_cb = Axes(fig1, divider.get_position())
h = [Size.AxesX(ax), # main axes
Size.Fixed(0.05), # padding, 0.1 inch
Size.Fixed(0.2), # colorbar, 0.3 inch
]
v = [Size.AxesY(ax)]
divider.set_horizontal(h)
divider.set_vertical(v)
ax.set_axes_locator(divider.new_locator(nx=0, ny=0))
ax_cb.set_axes_locator(divider.new_locator(nx=2, ny=0))
fig1.add_axes(ax)
fig1.add_axes(ax_cb)
ax_cb.axis["left"].toggle(all=False)
ax_cb.axis["right"].toggle(ticks=True)
Z, extent = get_demo_image()
im = ax.imshow(Z, extent=extent, interpolation="nearest")
plt.colorbar(im, cax=ax_cb)
plt.setp(ax_cb.get_yticklabels(), visible=False)
def demo_locatable_axes_easy(ax):
from mpl_toolkits.axes_grid1 import make_axes_locatable
divider = make_axes_locatable(ax)
ax_cb = divider.new_horizontal(size="5%", pad=0.05)
fig1 = ax.get_figure()
fig1.add_axes(ax_cb)
Z, extent = get_demo_image()
im = ax.imshow(Z, extent=extent, interpolation="nearest")
plt.colorbar(im, cax=ax_cb)
ax_cb.yaxis.tick_right()
ax_cb.yaxis.set_tick_params(labelright=False)
def demo_images_side_by_side(ax):
from mpl_toolkits.axes_grid1 import make_axes_locatable
divider = make_axes_locatable(ax)
Z, extent = get_demo_image()
ax2 = divider.new_horizontal(size="100%", pad=0.05)
fig1 = ax.get_figure()
fig1.add_axes(ax2)
ax.imshow(Z, extent=extent, interpolation="nearest")
ax2.imshow(Z, extent=extent, interpolation="nearest")
ax2.yaxis.set_tick_params(labelleft=False)
def demo():
fig1 = plt.figure(1, (6, 6))
fig1.clf()
# PLOT 1
# simple image & colorbar
ax = fig1.add_subplot(2, 2, 1)
demo_simple_image(ax)
# PLOT 2
# image and colorbar whose location is adjusted in the drawing time.
# a hard way
demo_locatable_axes_hard(fig1)
# PLOT 3
# image and colorbar whose location is adjusted in the drawing time.
# a easy way
ax = fig1.add_subplot(2, 2, 3)
demo_locatable_axes_easy(ax)
# PLOT 4
# two images side by side with fixed padding.
ax = fig1.add_subplot(2, 2, 4)
demo_images_side_by_side(ax)
plt.show()
demo()
```
## 下载这个示例
- [下载python源码: demo_axes_divider.py](https://matplotlib.org/_downloads/demo_axes_divider.py)
- [下载Jupyter notebook: demo_axes_divider.ipynb](https://matplotlib.org/_downloads/demo_axes_divider.ipynb)

View File

@@ -0,0 +1,144 @@
# 演示Axes Grid
具有单个或自己的彩条的2x2图像的网格。
![演示Axes Grid](https://matplotlib.org/_images/sphx_glr_demo_axes_grid_0011.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid
def get_demo_image():
import numpy as np
from matplotlib.cbook import get_sample_data
f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False)
z = np.load(f)
# z is a numpy array of 15x15
return z, (-3, 4, -4, 3)
def demo_simple_grid(fig):
"""
A grid of 2x2 images with 0.05 inch pad between images and only
the lower-left axes is labeled.
"""
grid = ImageGrid(fig, 141, # similar to subplot(141)
nrows_ncols=(2, 2),
axes_pad=0.05,
label_mode="1",
)
Z, extent = get_demo_image()
for i in range(4):
im = grid[i].imshow(Z, extent=extent, interpolation="nearest")
# This only affects axes in first column and second row as share_all =
# False.
grid.axes_llc.set_xticks([-2, 0, 2])
grid.axes_llc.set_yticks([-2, 0, 2])
def demo_grid_with_single_cbar(fig):
"""
A grid of 2x2 images with a single colorbar
"""
grid = ImageGrid(fig, 142, # similar to subplot(142)
nrows_ncols=(2, 2),
axes_pad=0.0,
share_all=True,
label_mode="L",
cbar_location="top",
cbar_mode="single",
)
Z, extent = get_demo_image()
for i in range(4):
im = grid[i].imshow(Z, extent=extent, interpolation="nearest")
grid.cbar_axes[0].colorbar(im)
for cax in grid.cbar_axes:
cax.toggle_label(False)
# This affects all axes as share_all = True.
grid.axes_llc.set_xticks([-2, 0, 2])
grid.axes_llc.set_yticks([-2, 0, 2])
def demo_grid_with_each_cbar(fig):
"""
A grid of 2x2 images. Each image has its own colorbar.
"""
grid = ImageGrid(fig, 143, # similar to subplot(143)
nrows_ncols=(2, 2),
axes_pad=0.1,
label_mode="1",
share_all=True,
cbar_location="top",
cbar_mode="each",
cbar_size="7%",
cbar_pad="2%",
)
Z, extent = get_demo_image()
for i in range(4):
im = grid[i].imshow(Z, extent=extent, interpolation="nearest")
grid.cbar_axes[i].colorbar(im)
for cax in grid.cbar_axes:
cax.toggle_label(False)
# This affects all axes because we set share_all = True.
grid.axes_llc.set_xticks([-2, 0, 2])
grid.axes_llc.set_yticks([-2, 0, 2])
def demo_grid_with_each_cbar_labelled(fig):
"""
A grid of 2x2 images. Each image has its own colorbar.
"""
grid = ImageGrid(fig, 144, # similar to subplot(144)
nrows_ncols=(2, 2),
axes_pad=(0.45, 0.15),
label_mode="1",
share_all=True,
cbar_location="right",
cbar_mode="each",
cbar_size="7%",
cbar_pad="2%",
)
Z, extent = get_demo_image()
# Use a different colorbar range every time
limits = ((0, 1), (-2, 2), (-1.7, 1.4), (-1.5, 1))
for i in range(4):
im = grid[i].imshow(Z, extent=extent, interpolation="nearest",
vmin=limits[i][0], vmax=limits[i][1])
grid.cbar_axes[i].colorbar(im)
for i, cax in enumerate(grid.cbar_axes):
cax.set_yticks((limits[i][0], limits[i][1]))
# This affects all axes because we set share_all = True.
grid.axes_llc.set_xticks([-2, 0, 2])
grid.axes_llc.set_yticks([-2, 0, 2])
if 1:
F = plt.figure(1, (10.5, 2.5))
F.subplots_adjust(left=0.05, right=0.95)
demo_simple_grid(F)
demo_grid_with_single_cbar(F)
demo_grid_with_each_cbar(F)
demo_grid_with_each_cbar_labelled(F)
plt.show()
```
## 下载这个示例
- [下载python源码: demo_axes_grid.py](https://matplotlib.org/_downloads/demo_axes_grid.py)
- [下载Jupyter notebook: demo_axes_grid.ipynb](https://matplotlib.org/_downloads/demo_axes_grid.ipynb)

View File

@@ -0,0 +1,125 @@
# 演示Axes Grid2
共享xaxis和yaxis的图像网格。
![演示Axes Grid2](https://matplotlib.org/_images/sphx_glr_demo_axes_grid2_001.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid
import numpy as np
def get_demo_image():
from matplotlib.cbook import get_sample_data
f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False)
z = np.load(f)
# z is a numpy array of 15x15
return z, (-3, 4, -4, 3)
def add_inner_title(ax, title, loc, size=None, **kwargs):
from matplotlib.offsetbox import AnchoredText
from matplotlib.patheffects import withStroke
if size is None:
size = dict(size=plt.rcParams['legend.fontsize'])
at = AnchoredText(title, loc=loc, prop=size,
pad=0., borderpad=0.5,
frameon=False, **kwargs)
ax.add_artist(at)
at.txt._text.set_path_effects([withStroke(foreground="w", linewidth=3)])
return at
if 1:
F = plt.figure(1, (6, 6))
F.clf()
# prepare images
Z, extent = get_demo_image()
ZS = [Z[i::3, :] for i in range(3)]
extent = extent[0], extent[1]/3., extent[2], extent[3]
# demo 1 : colorbar at each axes
grid = ImageGrid(F, 211, # similar to subplot(111)
nrows_ncols=(1, 3),
direction="row",
axes_pad=0.05,
add_all=True,
label_mode="1",
share_all=True,
cbar_location="top",
cbar_mode="each",
cbar_size="7%",
cbar_pad="1%",
)
for ax, z in zip(grid, ZS):
im = ax.imshow(
z, origin="lower", extent=extent, interpolation="nearest")
ax.cax.colorbar(im)
for ax, im_title in zip(grid, ["Image 1", "Image 2", "Image 3"]):
t = add_inner_title(ax, im_title, loc='lower left')
t.patch.set_alpha(0.5)
for ax, z in zip(grid, ZS):
ax.cax.toggle_label(True)
#axis = ax.cax.axis[ax.cax.orientation]
#axis.label.set_text("counts s$^{-1}$")
#axis.label.set_size(10)
#axis.major_ticklabels.set_size(6)
# changing the colorbar ticks
grid[1].cax.set_xticks([-1, 0, 1])
grid[2].cax.set_xticks([-1, 0, 1])
grid[0].set_xticks([-2, 0])
grid[0].set_yticks([-2, 0, 2])
# demo 2 : shared colorbar
grid2 = ImageGrid(F, 212,
nrows_ncols=(1, 3),
direction="row",
axes_pad=0.05,
add_all=True,
label_mode="1",
share_all=True,
cbar_location="right",
cbar_mode="single",
cbar_size="10%",
cbar_pad=0.05,
)
grid2[0].set_xlabel("X")
grid2[0].set_ylabel("Y")
vmax, vmin = np.max(ZS), np.min(ZS)
import matplotlib.colors
norm = matplotlib.colors.Normalize(vmax=vmax, vmin=vmin)
for ax, z in zip(grid2, ZS):
im = ax.imshow(z, norm=norm,
origin="lower", extent=extent,
interpolation="nearest")
# With cbar_mode="single", cax attribute of all axes are identical.
ax.cax.colorbar(im)
ax.cax.toggle_label(True)
for ax, im_title in zip(grid2, ["(a)", "(b)", "(c)"]):
t = add_inner_title(ax, im_title, loc='upper left')
t.patch.set_ec("none")
t.patch.set_alpha(0.5)
grid2[0].set_xticks([-2, 0])
grid2[0].set_yticks([-2, 0, 2])
plt.show()
```
## 下载这个示例
- [下载python源码: demo_axes_grid2.py](https://matplotlib.org/_downloads/demo_axes_grid2.py)
- [下载Jupyter notebook: demo_axes_grid2.ipynb](https://matplotlib.org/_downloads/demo_axes_grid2.ipynb)

View File

@@ -0,0 +1,62 @@
# 演示轴 Hbox Divider
HBox Divider用于排列子图。
![演示轴 Hbox Divider](https://matplotlib.org/_images/sphx_glr_demo_axes_hbox_divider_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.axes_divider import HBoxDivider
import mpl_toolkits.axes_grid1.axes_size as Size
def make_heights_equal(fig, rect, ax1, ax2, pad):
# pad in inches
h1, v1 = Size.AxesX(ax1), Size.AxesY(ax1)
h2, v2 = Size.AxesX(ax2), Size.AxesY(ax2)
pad_v = Size.Scaled(1)
pad_h = Size.Fixed(pad)
my_divider = HBoxDivider(fig, rect,
horizontal=[h1, pad_h, h2],
vertical=[v1, pad_v, v2])
ax1.set_axes_locator(my_divider.new_locator(0))
ax2.set_axes_locator(my_divider.new_locator(2))
if __name__ == "__main__":
arr1 = np.arange(20).reshape((4, 5))
arr2 = np.arange(20).reshape((5, 4))
fig, (ax1, ax2) = plt.subplots(1, 2)
ax1.imshow(arr1, interpolation="nearest")
ax2.imshow(arr2, interpolation="nearest")
rect = 111 # subplot param for combined axes
make_heights_equal(fig, rect, ax1, ax2, pad=0.5) # pad in inches
for ax in [ax1, ax2]:
ax.locator_params(nbins=4)
# annotate
ax3 = plt.axes([0.5, 0.5, 0.001, 0.001], frameon=False)
ax3.xaxis.set_visible(False)
ax3.yaxis.set_visible(False)
ax3.annotate("Location of two axes are adjusted\n"
"so that they have equal heights\n"
"while maintaining their aspect ratios", (0.5, 0.5),
xycoords="axes fraction", va="center", ha="center",
bbox=dict(boxstyle="round, pad=1", fc="w"))
plt.show()
```
## 下载这个示例
- [下载python源码: demo_axes_hbox_divider.py](https://matplotlib.org/_downloads/demo_axes_hbox_divider.py)
- [下载Jupyter notebook: demo_axes_hbox_divider.ipynb](https://matplotlib.org/_downloads/demo_axes_hbox_divider.ipynb)

View File

@@ -0,0 +1,99 @@
# 演示轴 RGB
RGBAxes显示RGB合成图像。
![演示轴 RGB](https://matplotlib.org/_images/sphx_glr_demo_axes_rgb_001.png)
![演示轴 RGB2](https://matplotlib.org/_images/sphx_glr_demo_axes_rgb_002.png)
```python
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.axes_rgb import make_rgb_axes, RGBAxes
def get_demo_image():
from matplotlib.cbook import get_sample_data
f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False)
z = np.load(f)
# z is a numpy array of 15x15
return z, (-3, 4, -4, 3)
def get_rgb():
Z, extent = get_demo_image()
Z[Z < 0] = 0.
Z = Z/Z.max()
R = Z[:13, :13]
G = Z[2:, 2:]
B = Z[:13, 2:]
return R, G, B
def make_cube(r, g, b):
ny, nx = r.shape
R = np.zeros([ny, nx, 3], dtype="d")
R[:, :, 0] = r
G = np.zeros_like(R)
G[:, :, 1] = g
B = np.zeros_like(R)
B[:, :, 2] = b
RGB = R + G + B
return R, G, B, RGB
def demo_rgb():
fig, ax = plt.subplots()
ax_r, ax_g, ax_b = make_rgb_axes(ax, pad=0.02)
#fig.add_axes(ax_r)
#fig.add_axes(ax_g)
#fig.add_axes(ax_b)
r, g, b = get_rgb()
im_r, im_g, im_b, im_rgb = make_cube(r, g, b)
kwargs = dict(origin="lower", interpolation="nearest")
ax.imshow(im_rgb, **kwargs)
ax_r.imshow(im_r, **kwargs)
ax_g.imshow(im_g, **kwargs)
ax_b.imshow(im_b, **kwargs)
def demo_rgb2():
fig = plt.figure(2)
ax = RGBAxes(fig, [0.1, 0.1, 0.8, 0.8], pad=0.0)
#fig.add_axes(ax)
#ax.add_RGB_to_figure()
r, g, b = get_rgb()
kwargs = dict(origin="lower", interpolation="nearest")
ax.imshow_rgb(r, g, b, **kwargs)
ax.RGB.set_xlim(0., 9.5)
ax.RGB.set_ylim(0.9, 10.6)
for ax1 in [ax.RGB, ax.R, ax.G, ax.B]:
for sp1 in ax1.spines.values():
sp1.set_color("w")
for tick in ax1.xaxis.get_major_ticks() + ax1.yaxis.get_major_ticks():
tick.tick1line.set_mec("w")
tick.tick2line.set_mec("w")
return ax
demo_rgb()
ax = demo_rgb2()
plt.show()
```
## 下载这个示例
- [下载python源码: demo_axes_rgb.py](https://matplotlib.org/_downloads/demo_axes_rgb.py)
- [下载Jupyter notebook: demo_axes_rgb.ipynb](https://matplotlib.org/_downloads/demo_axes_rgb.ipynb)

View File

@@ -0,0 +1,57 @@
# 演示嵌入轴颜色条
![演示嵌入轴颜色条](https://matplotlib.org/_images/sphx_glr_demo_colorbar_of_inset_axes_001.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes, zoomed_inset_axes
from mpl_toolkits.axes_grid1.colorbar import colorbar
def get_demo_image():
from matplotlib.cbook import get_sample_data
import numpy as np
f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False)
z = np.load(f)
# z is a numpy array of 15x15
return z, (-3, 4, -4, 3)
fig, ax = plt.subplots(figsize=[5, 4])
Z, extent = get_demo_image()
ax.set(aspect=1,
xlim=(-15, 15),
ylim=(-20, 5))
axins = zoomed_inset_axes(ax, zoom=2, loc='upper left')
im = axins.imshow(Z, extent=extent, interpolation="nearest",
origin="lower")
plt.xticks(visible=False)
plt.yticks(visible=False)
# colorbar
cax = inset_axes(axins,
width="5%", # width = 10% of parent_bbox width
height="100%", # height : 50%
loc='lower left',
bbox_to_anchor=(1.05, 0., 1, 1),
bbox_transform=axins.transAxes,
borderpad=0,
)
colorbar(im, cax=cax)
plt.show()
```
## 下载这个示例
- [下载python源码: demo_colorbar_of_inset_axes.py](https://matplotlib.org/_downloads/demo_colorbar_of_inset_axes.py)
- [下载Jupyter notebook: demo_colorbar_of_inset_axes.ipynb](https://matplotlib.org/_downloads/demo_colorbar_of_inset_axes.ipynb)

View File

@@ -0,0 +1,30 @@
# 演示带轴分割器的颜色条
![演示带轴分割器的颜色条](https://matplotlib.org/_images/sphx_glr_demo_colorbar_with_axes_divider_001.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.axes_divider import make_axes_locatable
from mpl_toolkits.axes_grid1.colorbar import colorbar
fig, (ax1, ax2) = plt.subplots(1, 2)
fig.subplots_adjust(wspace=0.5)
im1 = ax1.imshow([[1, 2], [3, 4]])
ax1_divider = make_axes_locatable(ax1)
cax1 = ax1_divider.append_axes("right", size="7%", pad="2%")
cb1 = colorbar(im1, cax=cax1)
im2 = ax2.imshow([[1, 2], [3, 4]])
ax2_divider = make_axes_locatable(ax2)
cax2 = ax2_divider.append_axes("top", size="7%", pad="2%")
cb2 = colorbar(im2, cax=cax2, orientation="horizontal")
cax2.xaxis.set_ticks_position("top")
plt.show()
```
## 下载这个示例
- [下载python源码: demo_colorbar_with_axes_divider.py](https://matplotlib.org/_downloads/demo_colorbar_with_axes_divider.py)
- [下载Jupyter notebook: demo_colorbar_with_axes_divider.ipynb](https://matplotlib.org/_downloads/demo_colorbar_with_axes_divider.ipynb)

View File

@@ -0,0 +1,43 @@
# 使用插入定位器演示Colorbar
![使用插入定位器演示Colorbar](https://matplotlib.org/_images/sphx_glr_demo_colorbar_with_inset_locator_001.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=[6, 3])
axins1 = inset_axes(ax1,
width="50%", # width = 10% of parent_bbox width
height="5%", # height : 50%
loc='upper right')
im1 = ax1.imshow([[1, 2], [2, 3]])
plt.colorbar(im1, cax=axins1, orientation="horizontal", ticks=[1, 2, 3])
axins1.xaxis.set_ticks_position("bottom")
axins = inset_axes(ax2,
width="5%", # width = 10% of parent_bbox width
height="50%", # height : 50%
loc='lower left',
bbox_to_anchor=(1.05, 0., 1, 1),
bbox_transform=ax2.transAxes,
borderpad=0,
)
# Controlling the placement of the inset axes is basically same as that
# of the legend. you may want to play with the borderpad value and
# the bbox_to_anchor coordinate.
im = ax2.imshow([[1, 2], [2, 3]])
plt.colorbar(im, cax=axins, ticks=[1, 2, 3])
plt.show()
```
## 下载这个示例
- [下载python源码: demo_colorbar_with_inset_locator.py](https://matplotlib.org/_downloads/demo_colorbar_with_inset_locator.py)
- [下载Jupyter notebook: demo_colorbar_with_inset_locator.ipynb](https://matplotlib.org/_downloads/demo_colorbar_with_inset_locator.ipynb)

View File

@@ -0,0 +1,98 @@
# 演示Edge Colorbar
![演示Edge Colorbar](https://matplotlib.org/_images/sphx_glr_demo_edge_colorbar_001.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import AxesGrid
def get_demo_image():
import numpy as np
from matplotlib.cbook import get_sample_data
f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False)
z = np.load(f)
# z is a numpy array of 15x15
return z, (-3, 4, -4, 3)
def demo_bottom_cbar(fig):
"""
A grid of 2x2 images with a colorbar for each column.
"""
grid = AxesGrid(fig, 121, # similar to subplot(132)
nrows_ncols=(2, 2),
axes_pad=0.10,
share_all=True,
label_mode="1",
cbar_location="bottom",
cbar_mode="edge",
cbar_pad=0.25,
cbar_size="15%",
direction="column"
)
Z, extent = get_demo_image()
cmaps = [plt.get_cmap("autumn"), plt.get_cmap("summer")]
for i in range(4):
im = grid[i].imshow(Z, extent=extent, interpolation="nearest",
cmap=cmaps[i//2])
if i % 2:
cbar = grid.cbar_axes[i//2].colorbar(im)
for cax in grid.cbar_axes:
cax.toggle_label(True)
cax.axis[cax.orientation].set_label("Bar")
# This affects all axes as share_all = True.
grid.axes_llc.set_xticks([-2, 0, 2])
grid.axes_llc.set_yticks([-2, 0, 2])
def demo_right_cbar(fig):
"""
A grid of 2x2 images. Each row has its own colorbar.
"""
grid = AxesGrid(F, 122, # similar to subplot(122)
nrows_ncols=(2, 2),
axes_pad=0.10,
label_mode="1",
share_all=True,
cbar_location="right",
cbar_mode="edge",
cbar_size="7%",
cbar_pad="2%",
)
Z, extent = get_demo_image()
cmaps = [plt.get_cmap("spring"), plt.get_cmap("winter")]
for i in range(4):
im = grid[i].imshow(Z, extent=extent, interpolation="nearest",
cmap=cmaps[i//2])
if i % 2:
grid.cbar_axes[i//2].colorbar(im)
for cax in grid.cbar_axes:
cax.toggle_label(True)
cax.axis[cax.orientation].set_label('Foo')
# This affects all axes because we set share_all = True.
grid.axes_llc.set_xticks([-2, 0, 2])
grid.axes_llc.set_yticks([-2, 0, 2])
if 1:
F = plt.figure(1, (5.5, 2.5))
F.subplots_adjust(left=0.05, right=0.93)
demo_bottom_cbar(F)
demo_right_cbar(F)
plt.show()
```
## 下载这个示例
- [下载python源码: demo_edge_colorbar.py](https://matplotlib.org/_downloads/demo_edge_colorbar.py)
- [下载Jupyter notebook: demo_edge_colorbar.ipynb](https://matplotlib.org/_downloads/demo_edge_colorbar.ipynb)

View File

@@ -0,0 +1,62 @@
# 演示固定尺寸轴
![演示固定尺寸轴](https://matplotlib.org/_images/sphx_glr_demo_fixed_size_axes_001.png)
![演示固定尺寸轴2](https://matplotlib.org/_images/sphx_glr_demo_fixed_size_axes_002.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import Divider, Size
from mpl_toolkits.axes_grid1.mpl_axes import Axes
def demo_fixed_size_axes():
fig1 = plt.figure(1, (6, 6))
# The first items are for padding and the second items are for the axes.
# sizes are in inch.
h = [Size.Fixed(1.0), Size.Fixed(4.5)]
v = [Size.Fixed(0.7), Size.Fixed(5.)]
divider = Divider(fig1, (0.0, 0.0, 1., 1.), h, v, aspect=False)
# the width and height of the rectangle is ignored.
ax = Axes(fig1, divider.get_position())
ax.set_axes_locator(divider.new_locator(nx=1, ny=1))
fig1.add_axes(ax)
ax.plot([1, 2, 3])
def demo_fixed_pad_axes():
fig = plt.figure(2, (6, 6))
# The first & third items are for padding and the second items are for the
# axes. Sizes are in inches.
h = [Size.Fixed(1.0), Size.Scaled(1.), Size.Fixed(.2)]
v = [Size.Fixed(0.7), Size.Scaled(1.), Size.Fixed(.5)]
divider = Divider(fig, (0.0, 0.0, 1., 1.), h, v, aspect=False)
# the width and height of the rectangle is ignored.
ax = Axes(fig, divider.get_position())
ax.set_axes_locator(divider.new_locator(nx=1, ny=1))
fig.add_axes(ax)
ax.plot([1, 2, 3])
if __name__ == "__main__":
demo_fixed_size_axes()
demo_fixed_pad_axes()
plt.show()
```
## 下载这个示例
- [下载python源码: demo_fixed_size_axes.py](https://matplotlib.org/_downloads/demo_fixed_size_axes.py)
- [下载Jupyter notebook: demo_fixed_size_axes.ipynb](https://matplotlib.org/_downloads/demo_fixed_size_axes.ipynb)

View File

@@ -0,0 +1,31 @@
# 演示Imagegrid Aspect
![演示Imagegrid Aspect](https://matplotlib.org/_images/sphx_glr_demo_imagegrid_aspect_001.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid
fig = plt.figure(1)
grid1 = ImageGrid(fig, 121, (2, 2), axes_pad=0.1,
aspect=True, share_all=True)
for i in [0, 1]:
grid1[i].set_aspect(2)
grid2 = ImageGrid(fig, 122, (2, 2), axes_pad=0.1,
aspect=True, share_all=True)
for i in [1, 3]:
grid2[i].set_aspect(2)
plt.show()
```
## 下载这个示例
- [下载python源码: demo_imagegrid_aspect.py](https://matplotlib.org/_downloads/demo_imagegrid_aspect.py)
- [下载Jupyter notebook: demo_imagegrid_aspect.ipynb](https://matplotlib.org/_downloads/demo_imagegrid_aspect.ipynb)

View File

@@ -0,0 +1,137 @@
# 插入定位器演示
[inset_locator](https://matplotlib.org/api/_as_gen/mpl_toolkits.axes_grid1.inset_locator.html#module-mpl_toolkits.axes_grid1.inset_locator) 的 [inset_axes](https://matplotlib.org/api/_as_gen/mpl_toolkits.axes_grid1.inset_locator.inset_axes.html#mpl_toolkits.axes_grid1.inset_locator.inset_axes) 允许通过指定宽度和高度以及可选地将位置(Loc)接受位置作为代码(类似于[图例](https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.legend.html#matplotlib.axes.Axes.legend)),轻松地在轴的角中放置插入。默认情况下,通过“边界板”(BorderPad)参数控制的内嵌与轴之间的某些点偏移。
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
fig, (ax, ax2) = plt.subplots(1, 2, figsize=[5.5, 2.8])
# Create inset of width 1.3 inches and height 0.9 inches
# at the default upper right location
axins = inset_axes(ax, width=1.3, height=0.9)
# Create inset of width 30% and height 40% of the parent axes' bounding box
# at the lower left corner (loc=3)
axins2 = inset_axes(ax, width="30%", height="40%", loc=3)
# Create inset of mixed specifications in the second subplot;
# width is 30% of parent axes' bounding box and
# height is 1 inch at the upper left corner (loc=2)
axins3 = inset_axes(ax2, width="30%", height=1., loc=2)
# Create an inset in the lower right corner (loc=4) with borderpad=1, i.e.
# 10 points padding (as 10pt is the default fontsize) to the parent axes
axins4 = inset_axes(ax2, width="20%", height="20%", loc=4, borderpad=1)
# Turn ticklabels of insets off
for axi in [axins, axins2, axins3, axins4]:
axi.tick_params(labelleft=False, labelbottom=False)
plt.show()
```
![插入定位器演示](https://matplotlib.org/_images/sphx_glr_inset_locator_demo_001.png)
参数``bbox_to_anchor`` 和 ``bbox_transfrom`` 可用于对插入位置和大小进行更细粒度的控制,甚至可以将插入位置置于完全任意位置。``bbox_to_anchor`` 根据 ``bbox_transform`` 设置坐标中的边界框。
```python
fig = plt.figure(figsize=[5.5, 2.8])
ax = fig.add_subplot(121)
# We use the axes transform as bbox_transform. Therefore the bounding box
# needs to be specified in axes coordinates ((0,0) is the lower left corner
# of the axes, (1,1) is the upper right corner).
# The bounding box (.2, .4, .6, .5) starts at (.2,.4) and ranges to (.8,.9)
# in those coordinates.
# Inside of this bounding box an inset of half the bounding box' width and
# three quarters of the bounding box' height is created. The lower left corner
# of the inset is aligned to the lower left corner of the bounding box (loc=3).
# The inset is then offset by the default 0.5 in units of the font size.
axins = inset_axes(ax, width="50%", height="75%",
bbox_to_anchor=(.2, .4, .6, .5),
bbox_transform=ax.transAxes, loc=3)
# For visualization purposes we mark the bounding box by a rectangle
ax.add_patch(plt.Rectangle((.2, .4), .6, .5, ls="--", ec="c", fc="None",
transform=ax.transAxes))
# We set the axis limits to something other than the default, in order to not
# distract from the fact that axes coodinates are used here.
ax.axis([0, 10, 0, 10])
# Note how the two following insets are created at the same positions, one by
# use of the default parent axes' bbox and the other via a bbox in axes
# coordinates and the respective transform.
ax2 = fig.add_subplot(222)
axins2 = inset_axes(ax2, width="30%", height="50%")
ax3 = fig.add_subplot(224)
axins3 = inset_axes(ax3, width="100%", height="100%",
bbox_to_anchor=(.7, .5, .3, .5),
bbox_transform=ax3.transAxes)
# For visualization purposes we mark the bounding box by a rectangle
ax2.add_patch(plt.Rectangle((0, 0), 1, 1, ls="--", lw=2, ec="c", fc="None"))
ax3.add_patch(plt.Rectangle((.7, .5), .3, .5, ls="--", lw=2,
ec="c", fc="None"))
# Turn ticklabels off
for axi in [axins2, axins3, ax2, ax3]:
axi.tick_params(labelleft=False, labelbottom=False)
plt.show()
```
![插入定位器演示2](https://matplotlib.org/_images/sphx_glr_inset_locator_demo_002.png)
在上述方法中使用了轴变换和4元组边界框因为它主要用于指定相对于其所插入的轴的插入值。但是其他用例也是可能的。下面的示例检查其中一些。
```python
fig = plt.figure(figsize=[5.5, 2.8])
ax = fig.add_subplot(131)
# Create an inset outside the axes
axins = inset_axes(ax, width="100%", height="100%",
bbox_to_anchor=(1.05, .6, .5, .4),
bbox_transform=ax.transAxes, loc=2, borderpad=0)
axins.tick_params(left=False, right=True, labelleft=False, labelright=True)
# Create an inset with a 2-tuple bounding box. Note that this creates a
# bbox without extent. This hence only makes sense when specifying
# width and height in absolute units (inches).
axins2 = inset_axes(ax, width=0.5, height=0.4,
bbox_to_anchor=(0.33, 0.25),
bbox_transform=ax.transAxes, loc=3, borderpad=0)
ax2 = fig.add_subplot(133)
ax2.set_xscale("log")
ax2.axis([1e-6, 1e6, -2, 6])
# Create inset in data coordinates using ax.transData as transform
axins3 = inset_axes(ax2, width="100%", height="100%",
bbox_to_anchor=(1e-2, 2, 1e3, 3),
bbox_transform=ax2.transData, loc=2, borderpad=0)
# Create an inset horizontally centered in figure coordinates and vertically
# bound to line up with the axes.
from matplotlib.transforms import blended_transform_factory
transform = blended_transform_factory(fig.transFigure, ax2.transAxes)
axins4 = inset_axes(ax2, width="16%", height="34%",
bbox_to_anchor=(0, 0, 1, 1),
bbox_transform=transform, loc=8, borderpad=0)
plt.show()
```
![插入定位器演示3](https://matplotlib.org/_images/sphx_glr_inset_locator_demo_003.png)
## 下载这个示例
- [下载python源码: inset_locator_demo.py](https://matplotlib.org/_downloads/inset_locator_demo.py)
- [下载Jupyter notebook: inset_locator_demo.ipynb](https://matplotlib.org/_downloads/inset_locator_demo.ipynb)

View File

@@ -0,0 +1,89 @@
# 插入定位器演示2
本演示展示了如何通过 [zoomed_inset_axes](https://matplotlib.org/api/_as_gen/mpl_toolkits.axes_grid1.inset_locator.zoomed_inset_axes.html#mpl_toolkits.axes_grid1.inset_locator.zoomed_inset_axes) 创建缩放插图。 在第一个子图中,[AnchoredSizeBar](https://matplotlib.org/api/_as_gen/mpl_toolkits.axes_grid1.anchored_artists.AnchoredSizeBar.html#mpl_toolkits.axes_grid1.anchored_artists.AnchoredSizeBar) 显示缩放效果。 在第二个子图中,通过[mark_inset](https://matplotlib.org/api/_as_gen/mpl_toolkits.axes_grid1.inset_locator.mark_inset.html#mpl_toolkits.axes_grid1.inset_locator.mark_inset) 创建与感兴趣区域的连接。
![插入定位器演示2](https://matplotlib.org/_images/sphx_glr_inset_locator_demo2_001.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes, mark_inset
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar
import numpy as np
def get_demo_image():
from matplotlib.cbook import get_sample_data
import numpy as np
f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False)
z = np.load(f)
# z is a numpy array of 15x15
return z, (-3, 4, -4, 3)
fig, (ax, ax2) = plt.subplots(ncols=2, figsize=[6, 3])
# First subplot, showing an inset with a size bar.
ax.set_aspect(1)
axins = zoomed_inset_axes(ax, zoom=0.5, loc='upper right')
# fix the number of ticks on the inset axes
axins.yaxis.get_major_locator().set_params(nbins=7)
axins.xaxis.get_major_locator().set_params(nbins=7)
plt.setp(axins.get_xticklabels(), visible=False)
plt.setp(axins.get_yticklabels(), visible=False)
def add_sizebar(ax, size):
asb = AnchoredSizeBar(ax.transData,
size,
str(size),
loc=8,
pad=0.1, borderpad=0.5, sep=5,
frameon=False)
ax.add_artist(asb)
add_sizebar(ax, 0.5)
add_sizebar(axins, 0.5)
# Second subplot, showing an image with an inset zoom
# and a marked inset
Z, extent = get_demo_image()
Z2 = np.zeros([150, 150], dtype="d")
ny, nx = Z.shape
Z2[30:30 + ny, 30:30 + nx] = Z
# extent = [-3, 4, -4, 3]
ax2.imshow(Z2, extent=extent, interpolation="nearest",
origin="lower")
axins2 = zoomed_inset_axes(ax2, 6, loc=1) # zoom = 6
axins2.imshow(Z2, extent=extent, interpolation="nearest",
origin="lower")
# sub region of the original image
x1, x2, y1, y2 = -1.5, -0.9, -2.5, -1.9
axins2.set_xlim(x1, x2)
axins2.set_ylim(y1, y2)
# fix the number of ticks on the inset axes
axins2.yaxis.get_major_locator().set_params(nbins=7)
axins2.xaxis.get_major_locator().set_params(nbins=7)
plt.setp(axins2.get_xticklabels(), visible=False)
plt.setp(axins2.get_yticklabels(), visible=False)
# draw a bbox of the region of the inset axes in the parent axes and
# connecting lines between the bbox and the inset axes area
mark_inset(ax2, axins2, loc1=2, loc2=4, fc="none", ec="0.5")
plt.show()
```
## 下载这个示例
- [下载python源码: inset_locator_demo2.py](https://matplotlib.org/_downloads/inset_locator_demo2.py)
- [下载Jupyter notebook: inset_locator_demo2.ipynb](https://matplotlib.org/_downloads/inset_locator_demo2.ipynb)

View File

@@ -0,0 +1,76 @@
# 使用Axesgrid为Ylabel腾出空间
![使用Axesgrid为Ylabel腾出空间](https://matplotlib.org/_images/sphx_glr_make_room_for_ylabel_using_axesgrid_001.png)
![使用Axesgrid为Ylabel腾出空间示例1](https://matplotlib.org/_images/sphx_glr_make_room_for_ylabel_using_axesgrid_001.png)
![使用Axesgrid为Ylabel腾出空间示例2](https://matplotlib.org/_images/sphx_glr_make_room_for_ylabel_using_axesgrid_001.png)
```python
from mpl_toolkits.axes_grid1 import make_axes_locatable
from mpl_toolkits.axes_grid1.axes_divider import make_axes_area_auto_adjustable
if __name__ == "__main__":
import matplotlib.pyplot as plt
def ex1():
plt.figure(1)
ax = plt.axes([0, 0, 1, 1])
#ax = plt.subplot(111)
ax.set_yticks([0.5])
ax.set_yticklabels(["very long label"])
make_axes_area_auto_adjustable(ax)
def ex2():
plt.figure(2)
ax1 = plt.axes([0, 0, 1, 0.5])
ax2 = plt.axes([0, 0.5, 1, 0.5])
ax1.set_yticks([0.5])
ax1.set_yticklabels(["very long label"])
ax1.set_ylabel("Y label")
ax2.set_title("Title")
make_axes_area_auto_adjustable(ax1, pad=0.1, use_axes=[ax1, ax2])
make_axes_area_auto_adjustable(ax2, pad=0.1, use_axes=[ax1, ax2])
def ex3():
fig = plt.figure(3)
ax1 = plt.axes([0, 0, 1, 1])
divider = make_axes_locatable(ax1)
ax2 = divider.new_horizontal("100%", pad=0.3, sharey=ax1)
ax2.tick_params(labelleft=False)
fig.add_axes(ax2)
divider.add_auto_adjustable_area(use_axes=[ax1], pad=0.1,
adjust_dirs=["left"])
divider.add_auto_adjustable_area(use_axes=[ax2], pad=0.1,
adjust_dirs=["right"])
divider.add_auto_adjustable_area(use_axes=[ax1, ax2], pad=0.1,
adjust_dirs=["top", "bottom"])
ax1.set_yticks([0.5])
ax1.set_yticklabels(["very long label"])
ax2.set_title("Title")
ax2.set_xlabel("X - Label")
ex1()
ex2()
ex3()
plt.show()
```
## 下载这个示例
- [下载python源码: make_room_for_ylabel_using_axesgrid.py](https://matplotlib.org/_downloads/make_room_for_ylabel_using_axesgrid.py)
- [下载Jupyter notebook: make_room_for_ylabel_using_axesgrid.ipynb](https://matplotlib.org/_downloads/make_room_for_ylabel_using_axesgrid.ipynb)

View File

@@ -0,0 +1,34 @@
# 简单寄生示例
![简单寄生示例](https://matplotlib.org/_images/sphx_glr_parasite_simple_001.png)
```python
from mpl_toolkits.axes_grid1 import host_subplot
import matplotlib.pyplot as plt
host = host_subplot(111)
par = host.twinx()
host.set_xlabel("Distance")
host.set_ylabel("Density")
par.set_ylabel("Temperature")
p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density")
p2, = par.plot([0, 1, 2], [0, 3, 2], label="Temperature")
leg = plt.legend()
host.yaxis.get_label().set_color(p1.get_color())
leg.texts[0].set_color(p1.get_color())
par.yaxis.get_label().set_color(p2.get_color())
leg.texts[1].set_color(p2.get_color())
plt.show()
```
## 下载这个示例
- [下载python源码: parasite_simple.py](https://matplotlib.org/_downloads/parasite_simple.py)
- [下载Jupyter notebook: parasite_simple.ipynb](https://matplotlib.org/_downloads/parasite_simple.ipynb)

View File

@@ -0,0 +1,52 @@
# 简单寄生示例2
![简单寄生示例2](https://matplotlib.org/_images/sphx_glr_parasite_simple2_001.png)
```python
import matplotlib.transforms as mtransforms
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.parasite_axes import SubplotHost
obs = [["01_S1", 3.88, 0.14, 1970, 63],
["01_S4", 5.6, 0.82, 1622, 150],
["02_S1", 2.4, 0.54, 1570, 40],
["03_S1", 4.1, 0.62, 2380, 170]]
fig = plt.figure()
ax_kms = SubplotHost(fig, 1, 1, 1, aspect=1.)
# angular proper motion("/yr) to linear velocity(km/s) at distance=2.3kpc
pm_to_kms = 1./206265.*2300*3.085e18/3.15e7/1.e5
aux_trans = mtransforms.Affine2D().scale(pm_to_kms, 1.)
ax_pm = ax_kms.twin(aux_trans)
ax_pm.set_viewlim_mode("transform")
fig.add_subplot(ax_kms)
for n, ds, dse, w, we in obs:
time = ((2007 + (10. + 4/30.)/12) - 1988.5)
v = ds / time * pm_to_kms
ve = dse / time * pm_to_kms
ax_kms.errorbar([v], [w], xerr=[ve], yerr=[we], color="k")
ax_kms.axis["bottom"].set_label("Linear velocity at 2.3 kpc [km/s]")
ax_kms.axis["left"].set_label("FWHM [km/s]")
ax_pm.axis["top"].set_label(r"Proper Motion [$''$/yr]")
ax_pm.axis["top"].label.set_visible(True)
ax_pm.axis["right"].major_ticklabels.set_visible(False)
ax_kms.set_xlim(950, 3700)
ax_kms.set_ylim(950, 3100)
# xlim and ylim of ax_pms will be automatically adjusted.
plt.show()
```
## 下载这个示例
- [下载python源码: parasite_simple2.py](https://matplotlib.org/_downloads/parasite_simple2.py)
- [下载Jupyter notebook: parasite_simple2.ipynb](https://matplotlib.org/_downloads/parasite_simple2.ipynb)

View File

@@ -0,0 +1,59 @@
# 散点图
![散点图示例](https://matplotlib.org/_images/sphx_glr_scatter_hist_locatable_axes_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
# Fixing random state for reproducibility
np.random.seed(19680801)
# the random data
x = np.random.randn(1000)
y = np.random.randn(1000)
fig, axScatter = plt.subplots(figsize=(5.5, 5.5))
# the scatter plot:
axScatter.scatter(x, y)
axScatter.set_aspect(1.)
# create new axes on the right and on the top of the current axes
# The first argument of the new_vertical(new_horizontal) method is
# the height (width) of the axes to be created in inches.
divider = make_axes_locatable(axScatter)
axHistx = divider.append_axes("top", 1.2, pad=0.1, sharex=axScatter)
axHisty = divider.append_axes("right", 1.2, pad=0.1, sharey=axScatter)
# make some labels invisible
axHistx.xaxis.set_tick_params(labelbottom=False)
axHisty.yaxis.set_tick_params(labelleft=False)
# now determine nice limits by hand:
binwidth = 0.25
xymax = max(np.max(np.abs(x)), np.max(np.abs(y)))
lim = (int(xymax/binwidth) + 1)*binwidth
bins = np.arange(-lim, lim + binwidth, binwidth)
axHistx.hist(x, bins=bins)
axHisty.hist(y, bins=bins, orientation='horizontal')
# the xaxis of axHistx and yaxis of axHisty are shared with axScatter,
# thus there is no need to manually adjust the xlim and ylim of these
# axis.
axHistx.set_yticks([0, 50, 100])
axHisty.set_xticks([0, 50, 100])
plt.show()
```
## 下载这个示例
- [下载python源码: scatter_hist_locatable_axes.py](https://matplotlib.org/_downloads/scatter_hist_locatable_axes.py)
- [下载Jupyter notebook: scatter_hist_locatable_axes.ipynb](https://matplotlib.org/_downloads/scatter_hist_locatable_axes.ipynb)

View File

@@ -0,0 +1,86 @@
# 简单锚定艺术家对象示例
此示例说明如何使用在 [offsetbox](https://matplotlib.org/api/offsetbox_api.html#module-matplotlib.offsetbox) 和 [Matplotlib axes_grid1 Toolkit](https://matplotlib.org/api/toolkits/axes_grid1.html#toolkit-axesgrid1-index) 中找到的锚定辅助对象类。类似图形的实现,但不使用工具包,可以在[锚定的艺术家对象](https://matplotlib.org/gallery/misc/anchored_artists.html)中找到。
![简单锚定艺术家对象示例](https://matplotlib.org/_images/sphx_glr_simple_anchored_artists_001.png)
```python
import matplotlib.pyplot as plt
def draw_text(ax):
"""
Draw two text-boxes, anchored by different corners to the upper-left
corner of the figure.
"""
from matplotlib.offsetbox import AnchoredText
at = AnchoredText("Figure 1a",
loc='upper left', prop=dict(size=8), frameon=True,
)
at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
ax.add_artist(at)
at2 = AnchoredText("Figure 1(b)",
loc='lower left', prop=dict(size=8), frameon=True,
bbox_to_anchor=(0., 1.),
bbox_transform=ax.transAxes
)
at2.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
ax.add_artist(at2)
def draw_circle(ax):
"""
Draw a circle in axis coordinates
"""
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredDrawingArea
from matplotlib.patches import Circle
ada = AnchoredDrawingArea(20, 20, 0, 0,
loc='upper right', pad=0., frameon=False)
p = Circle((10, 10), 10)
ada.da.add_artist(p)
ax.add_artist(ada)
def draw_ellipse(ax):
"""
Draw an ellipse of width=0.1, height=0.15 in data coordinates
"""
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredEllipse
ae = AnchoredEllipse(ax.transData, width=0.1, height=0.15, angle=0.,
loc='lower left', pad=0.5, borderpad=0.4,
frameon=True)
ax.add_artist(ae)
def draw_sizebar(ax):
"""
Draw a horizontal bar with length of 0.1 in data coordinates,
with a fixed label underneath.
"""
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar
asb = AnchoredSizeBar(ax.transData,
0.1,
r"1$^{\prime}$",
loc='lower center',
pad=0.1, borderpad=0.5, sep=5,
frameon=False)
ax.add_artist(asb)
ax = plt.gca()
ax.set_aspect(1.)
draw_text(ax)
draw_circle(ax)
draw_ellipse(ax)
draw_sizebar(ax)
plt.show()
```
## 下载这个示例
- [下载python源码: simple_anchored_artists.py](https://matplotlib.org/_downloads/simple_anchored_artists.py)
- [下载Jupyter notebook: simple_anchored_artists.ipynb](https://matplotlib.org/_downloads/simple_anchored_artists.ipynb)

View File

@@ -0,0 +1,38 @@
# 简单轴分割器示例1
![简单轴分割器示例1](https://matplotlib.org/_images/sphx_glr_simple_axes_divider1_001.png)
```python
from mpl_toolkits.axes_grid1 import Size, Divider
import matplotlib.pyplot as plt
fig1 = plt.figure(1, (6, 6))
# fixed size in inch
horiz = [Size.Fixed(1.), Size.Fixed(.5), Size.Fixed(1.5),
Size.Fixed(.5)]
vert = [Size.Fixed(1.5), Size.Fixed(.5), Size.Fixed(1.)]
rect = (0.1, 0.1, 0.8, 0.8)
# divide the axes rectangle into grid whose size is specified by horiz * vert
divider = Divider(fig1, rect, horiz, vert, aspect=False)
# the rect parameter will be ignore as we will set axes_locator
ax1 = fig1.add_axes(rect, label="1")
ax2 = fig1.add_axes(rect, label="2")
ax3 = fig1.add_axes(rect, label="3")
ax4 = fig1.add_axes(rect, label="4")
ax1.set_axes_locator(divider.new_locator(nx=0, ny=0))
ax2.set_axes_locator(divider.new_locator(nx=0, ny=2))
ax3.set_axes_locator(divider.new_locator(nx=2, ny=2))
ax4.set_axes_locator(divider.new_locator(nx=2, nx1=4, ny=0))
plt.show()
```
## 下载这个示例
- [下载python源码: simple_axes_divider1.py](https://matplotlib.org/_downloads/simple_axes_divider1.py)
- [下载Jupyter notebook: simple_axes_divider1.ipynb](https://matplotlib.org/_downloads/simple_axes_divider1.ipynb)

View File

@@ -0,0 +1,38 @@
# 简单轴分割器示例2
![简单轴分割器示例2](https://matplotlib.org/_images/sphx_glr_simple_axes_divider2_001.png)
```python
import mpl_toolkits.axes_grid1.axes_size as Size
from mpl_toolkits.axes_grid1 import Divider
import matplotlib.pyplot as plt
fig1 = plt.figure(1, (5.5, 4.))
# the rect parameter will be ignore as we will set axes_locator
rect = (0.1, 0.1, 0.8, 0.8)
ax = [fig1.add_axes(rect, label="%d" % i) for i in range(4)]
horiz = [Size.Scaled(1.5), Size.Fixed(.5), Size.Scaled(1.),
Size.Scaled(.5)]
vert = [Size.Scaled(1.), Size.Fixed(.5), Size.Scaled(1.5)]
# divide the axes rectangle into grid whose size is specified by horiz * vert
divider = Divider(fig1, rect, horiz, vert, aspect=False)
ax[0].set_axes_locator(divider.new_locator(nx=0, ny=0))
ax[1].set_axes_locator(divider.new_locator(nx=0, ny=2))
ax[2].set_axes_locator(divider.new_locator(nx=2, ny=2))
ax[3].set_axes_locator(divider.new_locator(nx=2, nx1=4, ny=0))
for ax1 in ax:
ax1.tick_params(labelbottom=False, labelleft=False)
plt.show()
```
## 下载这个示例
- [下载python源码: simple_axes_divider2.py](https://matplotlib.org/_downloads/simple_axes_divider2.py)
- [下载Jupyter notebook: simple_axes_divider2.ipynb](https://matplotlib.org/_downloads/simple_axes_divider2.ipynb)

View File

@@ -0,0 +1,47 @@
# 简单轴分割器示例3
![简单轴分割器示例3](https://matplotlib.org/_images/sphx_glr_simple_axes_divider3_001.png)
```python
import mpl_toolkits.axes_grid1.axes_size as Size
from mpl_toolkits.axes_grid1 import Divider
import matplotlib.pyplot as plt
fig1 = plt.figure(1, (5.5, 4))
# the rect parameter will be ignore as we will set axes_locator
rect = (0.1, 0.1, 0.8, 0.8)
ax = [fig1.add_axes(rect, label="%d" % i) for i in range(4)]
horiz = [Size.AxesX(ax[0]), Size.Fixed(.5), Size.AxesX(ax[1])]
vert = [Size.AxesY(ax[0]), Size.Fixed(.5), Size.AxesY(ax[2])]
# divide the axes rectangle into grid whose size is specified by horiz * vert
divider = Divider(fig1, rect, horiz, vert, aspect=False)
ax[0].set_axes_locator(divider.new_locator(nx=0, ny=0))
ax[1].set_axes_locator(divider.new_locator(nx=2, ny=0))
ax[2].set_axes_locator(divider.new_locator(nx=0, ny=2))
ax[3].set_axes_locator(divider.new_locator(nx=2, ny=2))
ax[0].set_xlim(0, 2)
ax[1].set_xlim(0, 1)
ax[0].set_ylim(0, 1)
ax[2].set_ylim(0, 2)
divider.set_aspect(1.)
for ax1 in ax:
ax1.tick_params(labelbottom=False, labelleft=False)
plt.show()
```
## 下载这个示例
- [下载python源码: simple_axes_divider3.py](https://matplotlib.org/_downloads/simple_axes_divider3.py)
- [下载Jupyter notebook: simple_axes_divider3.ipynb](https://matplotlib.org/_downloads/simple_axes_divider3.ipynb)

View File

@@ -0,0 +1,28 @@
# 简单的轴线网格
![简单的轴线网格](https://matplotlib.org/_images/sphx_glr_simple_axesgrid_001.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid
import numpy as np
im = np.arange(100).reshape((10, 10))
fig = plt.figure(1, (4., 4.))
grid = ImageGrid(fig, 111, # similar to subplot(111)
nrows_ncols=(2, 2), # creates 2x2 grid of axes
axes_pad=0.1, # pad between axes in inch.
)
for i in range(4):
grid[i].imshow(im) # The AxesGrid object work as a list of axes.
plt.show()
```
## 下载这个示例
- [下载python源码: simple_axesgrid.py](https://matplotlib.org/_downloads/simple_axesgrid.py)
- [下载Jupyter notebook: simple_axesgrid.ipynb](https://matplotlib.org/_downloads/simple_axesgrid.ipynb)

View File

@@ -0,0 +1,43 @@
# 简单的轴线网格2
![简单的轴线网格2](https://matplotlib.org/_images/sphx_glr_simple_axesgrid2_001.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid
def get_demo_image():
import numpy as np
from matplotlib.cbook import get_sample_data
f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False)
z = np.load(f)
# z is a numpy array of 15x15
return z, (-3, 4, -4, 3)
F = plt.figure(1, (5.5, 3.5))
grid = ImageGrid(F, 111, # similar to subplot(111)
nrows_ncols=(1, 3),
axes_pad=0.1,
add_all=True,
label_mode="L",
)
Z, extent = get_demo_image() # demo image
im1 = Z
im2 = Z[:, :10]
im3 = Z[:, 10:]
vmin, vmax = Z.min(), Z.max()
for i, im in enumerate([im1, im2, im3]):
ax = grid[i]
ax.imshow(im, origin="lower", vmin=vmin,
vmax=vmax, interpolation="nearest")
plt.show()
```
## 下载这个示例
- [下载python源码: simple_axesgrid2.py](https://matplotlib.org/_downloads/simple_axesgrid2.py)
- [下载Jupyter notebook: simple_axesgrid2.ipynb](https://matplotlib.org/_downloads/simple_axesgrid2.ipynb)

View File

@@ -0,0 +1,28 @@
# 简单的 Axisline4
![简单的 Axisline4](https://matplotlib.org/_images/sphx_glr_simple_axisline4_001.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import host_subplot
import numpy as np
ax = host_subplot(111)
xx = np.arange(0, 2*np.pi, 0.01)
ax.plot(xx, np.sin(xx))
ax2 = ax.twin() # ax2 is responsible for "top" axis and "right" axis
ax2.set_xticks([0., .5*np.pi, np.pi, 1.5*np.pi, 2*np.pi])
ax2.set_xticklabels(["$0$", r"$\frac{1}{2}\pi$",
r"$\pi$", r"$\frac{3}{2}\pi$", r"$2\pi$"])
ax2.axis["right"].major_ticklabels.set_visible(False)
ax2.axis["top"].major_ticklabels.set_visible(True)
plt.show()
```
## 下载这个示例
- [下载python源码: simple_axisline4.py](https://matplotlib.org/_downloads/simple_axisline4.py)
- [下载Jupyter notebook: simple_axisline4.ipynb](https://matplotlib.org/_downloads/simple_axisline4.ipynb)

View File

@@ -0,0 +1,24 @@
# 简单的彩色条实现
![简单的彩色条实现示例](https://matplotlib.org/_images/sphx_glr_simple_colorbar_001.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np
ax = plt.subplot(111)
im = ax.imshow(np.arange(100).reshape((10, 10)))
# create an axes on the right side of ax. The width of cax will be 5%
# of ax and the padding between cax and ax will be fixed at 0.05 inch.
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
plt.colorbar(im, cax=cax)
```
## 下载这个示例
- [下载python源码: simple_colorbar.py](https://matplotlib.org/_downloads/simple_colorbar.py)
- [下载Jupyter notebook: simple_colorbar.ipynb](https://matplotlib.org/_downloads/simple_colorbar.ipynb)

View File

@@ -0,0 +1,49 @@
# 简单的 RGB
![简单的RGB示例](https://matplotlib.org/_images/sphx_glr_simple_rgb_001.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.axes_rgb import RGBAxes
def get_demo_image():
import numpy as np
from matplotlib.cbook import get_sample_data
f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False)
z = np.load(f)
# z is a numpy array of 15x15
return z, (-3, 4, -4, 3)
def get_rgb():
Z, extent = get_demo_image()
Z[Z < 0] = 0.
Z = Z / Z.max()
R = Z[:13, :13]
G = Z[2:, 2:]
B = Z[:13, 2:]
return R, G, B
fig = plt.figure(1)
ax = RGBAxes(fig, [0.1, 0.1, 0.8, 0.8])
r, g, b = get_rgb()
kwargs = dict(origin="lower", interpolation="nearest")
ax.imshow_rgb(r, g, b, **kwargs)
ax.RGB.set_xlim(0., 9.5)
ax.RGB.set_ylim(0.9, 10.6)
plt.show()
```
## 下载这个示例
- [下载python源码: simple_rgb.py](https://matplotlib.org/_downloads/simple_rgb.py)
- [下载Jupyter notebook: simple_rgb.ipynb](https://matplotlib.org/_downloads/simple_rgb.ipynb)

View File

@@ -0,0 +1,37 @@
# 轴方向演示步骤01
![轴方向演示步骤01示例](https://matplotlib.org/_images/sphx_glr_axis_direction_demo_step01_001.png)
```python
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as axisartist
def setup_axes(fig, rect):
ax = axisartist.Subplot(fig, rect)
fig.add_axes(ax)
ax.set_ylim(-0.1, 1.5)
ax.set_yticks([0, 1])
ax.axis[:].set_visible(False)
ax.axis["x"] = ax.new_floating_axis(1, 0.5)
ax.axis["x"].set_axisline_style("->", size=1.5)
return ax
fig = plt.figure(figsize=(3, 2.5))
fig.subplots_adjust(top=0.8)
ax1 = setup_axes(fig, "111")
ax1.axis["x"].set_axis_direction("left")
plt.show()
```
## 下载这个示例
- [下载python源码: axis_direction_demo_step01.py](https://matplotlib.org/_downloads/axis_direction_demo_step01.py)
- [下载Jupyter notebook: axis_direction_demo_step01.ipynb](https://matplotlib.org/_downloads/axis_direction_demo_step01.ipynb)

View File

@@ -0,0 +1,48 @@
# 轴方向演示步骤02
![轴方向演示步骤02示例](https://matplotlib.org/_images/sphx_glr_axis_direction_demo_step02_001.png)
```python
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as axisartist
def setup_axes(fig, rect):
ax = axisartist.Subplot(fig, rect)
fig.add_axes(ax)
ax.set_ylim(-0.1, 1.5)
ax.set_yticks([0, 1])
#ax.axis[:].toggle(all=False)
#ax.axis[:].line.set_visible(False)
ax.axis[:].set_visible(False)
ax.axis["x"] = ax.new_floating_axis(1, 0.5)
ax.axis["x"].set_axisline_style("->", size=1.5)
return ax
fig = plt.figure(figsize=(6, 2.5))
fig.subplots_adjust(bottom=0.2, top=0.8)
ax1 = setup_axes(fig, "121")
ax1.axis["x"].set_ticklabel_direction("+")
ax1.annotate("ticklabel direction=$+$", (0.5, 0), xycoords="axes fraction",
xytext=(0, -10), textcoords="offset points",
va="top", ha="center")
ax2 = setup_axes(fig, "122")
ax2.axis["x"].set_ticklabel_direction("-")
ax2.annotate("ticklabel direction=$-$", (0.5, 0), xycoords="axes fraction",
xytext=(0, -10), textcoords="offset points",
va="top", ha="center")
plt.show()
```
## 下载这个示例
- [下载python源码: axis_direction_demo_step02.py](https://matplotlib.org/_downloads/axis_direction_demo_step02.py)
- [下载Jupyter notebook: axis_direction_demo_step02.ipynb](https://matplotlib.org/_downloads/axis_direction_demo_step02.ipynb)

View File

@@ -0,0 +1,52 @@
# 轴方向演示步骤03
![轴方向演示步骤03示例](https://matplotlib.org/_images/sphx_glr_axis_direction_demo_step03_001.png)
```python
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as axisartist
def setup_axes(fig, rect):
ax = axisartist.Subplot(fig, rect)
fig.add_axes(ax)
ax.set_ylim(-0.1, 1.5)
ax.set_yticks([0, 1])
#ax.axis[:].toggle(all=False)
#ax.axis[:].line.set_visible(False)
ax.axis[:].set_visible(False)
ax.axis["x"] = ax.new_floating_axis(1, 0.5)
ax.axis["x"].set_axisline_style("->", size=1.5)
return ax
fig = plt.figure(figsize=(6, 2.5))
fig.subplots_adjust(bottom=0.2, top=0.8)
ax1 = setup_axes(fig, "121")
ax1.axis["x"].label.set_text("Label")
ax1.axis["x"].toggle(ticklabels=False)
ax1.axis["x"].set_axislabel_direction("+")
ax1.annotate("label direction=$+$", (0.5, 0), xycoords="axes fraction",
xytext=(0, -10), textcoords="offset points",
va="top", ha="center")
ax2 = setup_axes(fig, "122")
ax2.axis["x"].label.set_text("Label")
ax2.axis["x"].toggle(ticklabels=False)
ax2.axis["x"].set_axislabel_direction("-")
ax2.annotate("label direction=$-$", (0.5, 0), xycoords="axes fraction",
xytext=(0, -10), textcoords="offset points",
va="top", ha="center")
plt.show()
```
## 下载这个示例
- [下载python源码: axis_direction_demo_step03.py](https://matplotlib.org/_downloads/axis_direction_demo_step03.py)
- [下载Jupyter notebook: axis_direction_demo_step03.ipynb](https://matplotlib.org/_downloads/axis_direction_demo_step03.ipynb)

View File

@@ -0,0 +1,65 @@
# 轴方向演示步骤04
![轴方向演示步骤04示例](https://matplotlib.org/_images/sphx_glr_axis_direction_demo_step04_001.png)
```python
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as axisartist
def setup_axes(fig, rect):
ax = axisartist.Subplot(fig, rect)
fig.add_axes(ax)
ax.set_ylim(-0.1, 1.5)
ax.set_yticks([0, 1])
ax.axis[:].set_visible(False)
ax.axis["x1"] = ax.new_floating_axis(1, 0.3)
ax.axis["x1"].set_axisline_style("->", size=1.5)
ax.axis["x2"] = ax.new_floating_axis(1, 0.7)
ax.axis["x2"].set_axisline_style("->", size=1.5)
return ax
fig = plt.figure(figsize=(6, 2.5))
fig.subplots_adjust(bottom=0.2, top=0.8)
ax1 = setup_axes(fig, "121")
ax1.axis["x1"].label.set_text("rotation=0")
ax1.axis["x1"].toggle(ticklabels=False)
ax1.axis["x2"].label.set_text("rotation=10")
ax1.axis["x2"].label.set_rotation(10)
ax1.axis["x2"].toggle(ticklabels=False)
ax1.annotate("label direction=$+$", (0.5, 0), xycoords="axes fraction",
xytext=(0, -10), textcoords="offset points",
va="top", ha="center")
ax2 = setup_axes(fig, "122")
ax2.axis["x1"].set_axislabel_direction("-")
ax2.axis["x2"].set_axislabel_direction("-")
ax2.axis["x1"].label.set_text("rotation=0")
ax2.axis["x1"].toggle(ticklabels=False)
ax2.axis["x2"].label.set_text("rotation=10")
ax2.axis["x2"].label.set_rotation(10)
ax2.axis["x2"].toggle(ticklabels=False)
ax2.annotate("label direction=$-$", (0.5, 0), xycoords="axes fraction",
xytext=(0, -10), textcoords="offset points",
va="top", ha="center")
plt.show()
```
## 下载这个示例
- [下载python源码: axis_direction_demo_step04.py](https://matplotlib.org/_downloads/axis_direction_demo_step04.py)
- [下载Jupyter notebook: axis_direction_demo_step04.ipynb](https://matplotlib.org/_downloads/axis_direction_demo_step04.ipynb)

View File

@@ -0,0 +1,101 @@
# 演示轴方向
![演示轴方向示例](https://matplotlib.org/_images/sphx_glr_demo_axis_direction_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist.angle_helper as angle_helper
import mpl_toolkits.axisartist.grid_finder as grid_finder
from matplotlib.projections import PolarAxes
from matplotlib.transforms import Affine2D
import mpl_toolkits.axisartist as axisartist
from mpl_toolkits.axisartist.grid_helper_curvelinear import \
GridHelperCurveLinear
def setup_axes(fig, rect):
"""
polar projection, but in a rectangular box.
"""
# see demo_curvelinear_grid.py for details
tr = Affine2D().scale(np.pi/180., 1.) + PolarAxes.PolarTransform()
extreme_finder = angle_helper.ExtremeFinderCycle(20, 20,
lon_cycle=360,
lat_cycle=None,
lon_minmax=None,
lat_minmax=(0, np.inf),
)
grid_locator1 = angle_helper.LocatorDMS(12)
grid_locator2 = grid_finder.MaxNLocator(5)
tick_formatter1 = angle_helper.FormatterDMS()
grid_helper = GridHelperCurveLinear(tr,
extreme_finder=extreme_finder,
grid_locator1=grid_locator1,
grid_locator2=grid_locator2,
tick_formatter1=tick_formatter1
)
ax1 = axisartist.Subplot(fig, rect, grid_helper=grid_helper)
ax1.axis[:].toggle(ticklabels=False)
fig.add_subplot(ax1)
ax1.set_aspect(1.)
ax1.set_xlim(-5, 12)
ax1.set_ylim(-5, 10)
return ax1
def add_floating_axis1(ax1):
ax1.axis["lat"] = axis = ax1.new_floating_axis(0, 30)
axis.label.set_text(r"$\theta = 30^{\circ}$")
axis.label.set_visible(True)
return axis
def add_floating_axis2(ax1):
ax1.axis["lon"] = axis = ax1.new_floating_axis(1, 6)
axis.label.set_text(r"$r = 6$")
axis.label.set_visible(True)
return axis
fig = plt.figure(1, figsize=(8, 4))
fig.clf()
fig.subplots_adjust(left=0.01, right=0.99, bottom=0.01, top=0.99,
wspace=0.01, hspace=0.01)
for i, d in enumerate(["bottom", "left", "top", "right"]):
ax1 = setup_axes(fig, rect=241++i)
axis = add_floating_axis1(ax1)
axis.set_axis_direction(d)
ax1.annotate(d, (0, 1), (5, -5),
xycoords="axes fraction", textcoords="offset points",
va="top", ha="left")
for i, d in enumerate(["bottom", "left", "top", "right"]):
ax1 = setup_axes(fig, rect=245++i)
axis = add_floating_axis2(ax1)
axis.set_axis_direction(d)
ax1.annotate(d, (0, 1), (5, -5),
xycoords="axes fraction", textcoords="offset points",
va="top", ha="left")
plt.show()
```
## 下载这个示例
- [下载python源码: demo_axis_direction.py](https://matplotlib.org/_downloads/demo_axis_direction.py)
- [下载Jupyter notebook: demo_axis_direction.ipynb](https://matplotlib.org/_downloads/demo_axis_direction.ipynb)

View File

@@ -0,0 +1,37 @@
# 轴线样式
此示例显示了轴样式的一些配置。
![轴线样式示例](https://matplotlib.org/_images/sphx_glr_demo_axisline_style_001.png)
```python
from mpl_toolkits.axisartist.axislines import SubplotZero
import matplotlib.pyplot as plt
import numpy as np
if 1:
fig = plt.figure(1)
ax = SubplotZero(fig, 111)
fig.add_subplot(ax)
for direction in ["xzero", "yzero"]:
# adds arrows at the ends of each axis
ax.axis[direction].set_axisline_style("-|>")
# adds X and Y-axis from the origin
ax.axis[direction].set_visible(True)
for direction in ["left", "right", "bottom", "top"]:
# hides borders
ax.axis[direction].set_visible(False)
x = np.linspace(-0.5, 1., 100)
ax.plot(x, np.sin(x*np.pi))
plt.show()
```
## 下载这个示例
- [下载python源码: demo_axisline_style.py](https://matplotlib.org/_downloads/demo_axisline_style.py)
- [下载Jupyter notebook: demo_axisline_style.ipynb](https://matplotlib.org/_downloads/demo_axisline_style.ipynb)

View File

@@ -0,0 +1,142 @@
# 演示Curvelinear网格
自定义网格和记号行。
此示例演示如何通过在网格上应用转换使用GridHelperCurve线性来定义自定义网格和注释行。这可以用作第二个打印上的演示用于在矩形框中创建极轴投影。
![Curvelinear网格示例](https://matplotlib.org/_images/sphx_glr_demo_curvelinear_grid_0011.png)
```python
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook
from mpl_toolkits.axisartist import Subplot
from mpl_toolkits.axisartist import SubplotHost, \
ParasiteAxesAuxTrans
from mpl_toolkits.axisartist.grid_helper_curvelinear import \
GridHelperCurveLinear
def curvelinear_test1(fig):
"""
grid for custom transform.
"""
def tr(x, y):
x, y = np.asarray(x), np.asarray(y)
return x, y - x
def inv_tr(x, y):
x, y = np.asarray(x), np.asarray(y)
return x, y + x
grid_helper = GridHelperCurveLinear((tr, inv_tr))
ax1 = Subplot(fig, 1, 2, 1, grid_helper=grid_helper)
# ax1 will have a ticks and gridlines defined by the given
# transform (+ transData of the Axes). Note that the transform of
# the Axes itself (i.e., transData) is not affected by the given
# transform.
fig.add_subplot(ax1)
xx, yy = tr([3, 6], [5.0, 10.])
ax1.plot(xx, yy, linewidth=2.0)
ax1.set_aspect(1.)
ax1.set_xlim(0, 10.)
ax1.set_ylim(0, 10.)
ax1.axis["t"] = ax1.new_floating_axis(0, 3.)
ax1.axis["t2"] = ax1.new_floating_axis(1, 7.)
ax1.grid(True, zorder=0)
import mpl_toolkits.axisartist.angle_helper as angle_helper
from matplotlib.projections import PolarAxes
from matplotlib.transforms import Affine2D
def curvelinear_test2(fig):
"""
polar projection, but in a rectangular box.
"""
# PolarAxes.PolarTransform takes radian. However, we want our coordinate
# system in degree
tr = Affine2D().scale(np.pi/180., 1.) + PolarAxes.PolarTransform()
# polar projection, which involves cycle, and also has limits in
# its coordinates, needs a special method to find the extremes
# (min, max of the coordinate within the view).
# 20, 20 : number of sampling points along x, y direction
extreme_finder = angle_helper.ExtremeFinderCycle(20, 20,
lon_cycle=360,
lat_cycle=None,
lon_minmax=None,
lat_minmax=(0, np.inf),
)
grid_locator1 = angle_helper.LocatorDMS(12)
# Find a grid values appropriate for the coordinate (degree,
# minute, second).
tick_formatter1 = angle_helper.FormatterDMS()
# And also uses an appropriate formatter. Note that,the
# acceptable Locator and Formatter class is a bit different than
# that of mpl's, and you cannot directly use mpl's Locator and
# Formatter here (but may be possible in the future).
grid_helper = GridHelperCurveLinear(tr,
extreme_finder=extreme_finder,
grid_locator1=grid_locator1,
tick_formatter1=tick_formatter1
)
ax1 = SubplotHost(fig, 1, 2, 2, grid_helper=grid_helper)
# make ticklabels of right and top axis visible.
ax1.axis["right"].major_ticklabels.set_visible(True)
ax1.axis["top"].major_ticklabels.set_visible(True)
# let right axis shows ticklabels for 1st coordinate (angle)
ax1.axis["right"].get_helper().nth_coord_ticks = 0
# let bottom axis shows ticklabels for 2nd coordinate (radius)
ax1.axis["bottom"].get_helper().nth_coord_ticks = 1
fig.add_subplot(ax1)
# A parasite axes with given transform
ax2 = ParasiteAxesAuxTrans(ax1, tr, "equal")
# note that ax2.transData == tr + ax1.transData
# Anything you draw in ax2 will match the ticks and grids of ax1.
ax1.parasites.append(ax2)
intp = cbook.simple_linear_interpolation
ax2.plot(intp(np.array([0, 30]), 50),
intp(np.array([10., 10.]), 50),
linewidth=2.0)
ax1.set_aspect(1.)
ax1.set_xlim(-5, 12)
ax1.set_ylim(-5, 10)
ax1.grid(True, zorder=0)
if 1:
fig = plt.figure(1, figsize=(7, 4))
fig.clf()
curvelinear_test1(fig)
curvelinear_test2(fig)
plt.show()
```
## 下载这个示例
- [下载python源码: demo_curvelinear_grid.py](https://matplotlib.org/_downloads/demo_curvelinear_grid.py)
- [下载Jupyter notebook: demo_curvelinear_grid.ipynb](https://matplotlib.org/_downloads/demo_curvelinear_grid.ipynb)

View File

@@ -0,0 +1,75 @@
# 演示Curvelinear网格2
自定义网格和记号行。
此示例演示如何通过在网格上应用转换使用GridHelperCurve线性来定义自定义网格和注释行。作为打印上的演示轴上将显示5x5矩阵。
![Curvelinear网格2示例](https://matplotlib.org/_images/sphx_glr_demo_curvelinear_grid2_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axisartist.grid_helper_curvelinear import \
GridHelperCurveLinear
from mpl_toolkits.axisartist.axislines import Subplot
import mpl_toolkits.axisartist.angle_helper as angle_helper
def curvelinear_test1(fig):
"""
grid for custom transform.
"""
def tr(x, y):
sgn = np.sign(x)
x, y = np.abs(np.asarray(x)), np.asarray(y)
return sgn*x**.5, y
def inv_tr(x, y):
sgn = np.sign(x)
x, y = np.asarray(x), np.asarray(y)
return sgn*x**2, y
extreme_finder = angle_helper.ExtremeFinderCycle(20, 20,
lon_cycle=None,
lat_cycle=None,
# (0, np.inf),
lon_minmax=None,
lat_minmax=None,
)
grid_helper = GridHelperCurveLinear((tr, inv_tr),
extreme_finder=extreme_finder)
ax1 = Subplot(fig, 111, grid_helper=grid_helper)
# ax1 will have a ticks and gridlines defined by the given
# transform (+ transData of the Axes). Note that the transform of
# the Axes itself (i.e., transData) is not affected by the given
# transform.
fig.add_subplot(ax1)
ax1.imshow(np.arange(25).reshape(5, 5),
vmax=50, cmap=plt.cm.gray_r,
interpolation="nearest",
origin="lower")
# tick density
grid_helper.grid_finder.grid_locator1._nbins = 6
grid_helper.grid_finder.grid_locator2._nbins = 6
if 1:
fig = plt.figure(1, figsize=(7, 4))
fig.clf()
curvelinear_test1(fig)
plt.show()
```
## 下载这个示例
- [下载python源码: demo_curvelinear_grid2.py](https://matplotlib.org/_downloads/demo_curvelinear_grid2.py)
- [下载Jupyter notebook: demo_curvelinear_grid2.ipynb](https://matplotlib.org/_downloads/demo_curvelinear_grid2.ipynb)

View File

@@ -0,0 +1,160 @@
# 演示浮动轴
浮动轴的演示。
```python
from matplotlib.transforms import Affine2D
import mpl_toolkits.axisartist.floating_axes as floating_axes
import numpy as np
import mpl_toolkits.axisartist.angle_helper as angle_helper
from matplotlib.projections import PolarAxes
from mpl_toolkits.axisartist.grid_finder import (FixedLocator, MaxNLocator,
DictFormatter)
import matplotlib.pyplot as plt
# Fixing random state for reproducibility
np.random.seed(19680801)
def setup_axes1(fig, rect):
"""
A simple one.
"""
tr = Affine2D().scale(2, 1).rotate_deg(30)
grid_helper = floating_axes.GridHelperCurveLinear(
tr, extremes=(-0.5, 3.5, 0, 4))
ax1 = floating_axes.FloatingSubplot(fig, rect, grid_helper=grid_helper)
fig.add_subplot(ax1)
aux_ax = ax1.get_aux_axes(tr)
grid_helper.grid_finder.grid_locator1._nbins = 4
grid_helper.grid_finder.grid_locator2._nbins = 4
return ax1, aux_ax
def setup_axes2(fig, rect):
"""
With custom locator and formatter.
Note that the extreme values are swapped.
"""
tr = PolarAxes.PolarTransform()
pi = np.pi
angle_ticks = [(0, r"$0$"),
(.25*pi, r"$\frac{1}{4}\pi$"),
(.5*pi, r"$\frac{1}{2}\pi$")]
grid_locator1 = FixedLocator([v for v, s in angle_ticks])
tick_formatter1 = DictFormatter(dict(angle_ticks))
grid_locator2 = MaxNLocator(2)
grid_helper = floating_axes.GridHelperCurveLinear(
tr, extremes=(.5*pi, 0, 2, 1),
grid_locator1=grid_locator1,
grid_locator2=grid_locator2,
tick_formatter1=tick_formatter1,
tick_formatter2=None)
ax1 = floating_axes.FloatingSubplot(fig, rect, grid_helper=grid_helper)
fig.add_subplot(ax1)
# create a parasite axes whose transData in RA, cz
aux_ax = ax1.get_aux_axes(tr)
aux_ax.patch = ax1.patch # for aux_ax to have a clip path as in ax
ax1.patch.zorder = 0.9 # but this has a side effect that the patch is
# drawn twice, and possibly over some other
# artists. So, we decrease the zorder a bit to
# prevent this.
return ax1, aux_ax
def setup_axes3(fig, rect):
"""
Sometimes, things like axis_direction need to be adjusted.
"""
# rotate a bit for better orientation
tr_rotate = Affine2D().translate(-95, 0)
# scale degree to radians
tr_scale = Affine2D().scale(np.pi/180., 1.)
tr = tr_rotate + tr_scale + PolarAxes.PolarTransform()
grid_locator1 = angle_helper.LocatorHMS(4)
tick_formatter1 = angle_helper.FormatterHMS()
grid_locator2 = MaxNLocator(3)
# Specify theta limits in degrees
ra0, ra1 = 8.*15, 14.*15
# Specify radial limits
cz0, cz1 = 0, 14000
grid_helper = floating_axes.GridHelperCurveLinear(
tr, extremes=(ra0, ra1, cz0, cz1),
grid_locator1=grid_locator1,
grid_locator2=grid_locator2,
tick_formatter1=tick_formatter1,
tick_formatter2=None)
ax1 = floating_axes.FloatingSubplot(fig, rect, grid_helper=grid_helper)
fig.add_subplot(ax1)
# adjust axis
ax1.axis["left"].set_axis_direction("bottom")
ax1.axis["right"].set_axis_direction("top")
ax1.axis["bottom"].set_visible(False)
ax1.axis["top"].set_axis_direction("bottom")
ax1.axis["top"].toggle(ticklabels=True, label=True)
ax1.axis["top"].major_ticklabels.set_axis_direction("top")
ax1.axis["top"].label.set_axis_direction("top")
ax1.axis["left"].label.set_text(r"cz [km$^{-1}$]")
ax1.axis["top"].label.set_text(r"$\alpha_{1950}$")
# create a parasite axes whose transData in RA, cz
aux_ax = ax1.get_aux_axes(tr)
aux_ax.patch = ax1.patch # for aux_ax to have a clip path as in ax
ax1.patch.zorder = 0.9 # but this has a side effect that the patch is
# drawn twice, and possibly over some other
# artists. So, we decrease the zorder a bit to
# prevent this.
return ax1, aux_ax
```
```python
fig = plt.figure(1, figsize=(8, 4))
fig.subplots_adjust(wspace=0.3, left=0.05, right=0.95)
ax1, aux_ax1 = setup_axes1(fig, 131)
aux_ax1.bar([0, 1, 2, 3], [3, 2, 1, 3])
ax2, aux_ax2 = setup_axes2(fig, 132)
theta = np.random.rand(10)*.5*np.pi
radius = np.random.rand(10) + 1.
aux_ax2.scatter(theta, radius)
ax3, aux_ax3 = setup_axes3(fig, 133)
theta = (8 + np.random.rand(10)*(14 - 8))*15. # in degrees
radius = np.random.rand(10)*14000.
aux_ax3.scatter(theta, radius)
plt.show()
```
![演示浮动轴](https://matplotlib.org/_images/sphx_glr_demo_floating_axes_001.png)
## 下载这个示例
- [下载python源码: demo_floating_axes.py](https://matplotlib.org/_downloads/demo_floating_axes.py)
- [下载Jupyter notebook: demo_floating_axes.ipynb](https://matplotlib.org/_downloads/demo_floating_axes.ipynb)

View File

@@ -0,0 +1,76 @@
# 演示浮动轴2
轴在矩形框内
以下代码演示了如何将浮动极坐标曲线放在矩形框内。 为了更好地了解极坐标曲线请查看demo_curvelinear_grid.py。
![演示浮动轴2](https://matplotlib.org/_images/sphx_glr_demo_floating_axis_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist.angle_helper as angle_helper
from matplotlib.projections import PolarAxes
from matplotlib.transforms import Affine2D
from mpl_toolkits.axisartist import SubplotHost
from mpl_toolkits.axisartist import GridHelperCurveLinear
def curvelinear_test2(fig):
"""Polar projection, but in a rectangular box.
"""
# see demo_curvelinear_grid.py for details
tr = Affine2D().scale(np.pi / 180., 1.) + PolarAxes.PolarTransform()
extreme_finder = angle_helper.ExtremeFinderCycle(20,
20,
lon_cycle=360,
lat_cycle=None,
lon_minmax=None,
lat_minmax=(0,
np.inf),
)
grid_locator1 = angle_helper.LocatorDMS(12)
tick_formatter1 = angle_helper.FormatterDMS()
grid_helper = GridHelperCurveLinear(tr,
extreme_finder=extreme_finder,
grid_locator1=grid_locator1,
tick_formatter1=tick_formatter1
)
ax1 = SubplotHost(fig, 1, 1, 1, grid_helper=grid_helper)
fig.add_subplot(ax1)
# Now creates floating axis
# floating axis whose first coordinate (theta) is fixed at 60
ax1.axis["lat"] = axis = ax1.new_floating_axis(0, 60)
axis.label.set_text(r"$\theta = 60^{\circ}$")
axis.label.set_visible(True)
# floating axis whose second coordinate (r) is fixed at 6
ax1.axis["lon"] = axis = ax1.new_floating_axis(1, 6)
axis.label.set_text(r"$r = 6$")
ax1.set_aspect(1.)
ax1.set_xlim(-5, 12)
ax1.set_ylim(-5, 10)
ax1.grid(True)
fig = plt.figure(1, figsize=(5, 5))
fig.clf()
curvelinear_test2(fig)
plt.show()
```
## 下载这个示例
- [下载python源码: demo_floating_axis.py](https://matplotlib.org/_downloads/demo_floating_axis.py)
- [下载Jupyter notebook: demo_floating_axis.ipynb](https://matplotlib.org/_downloads/demo_floating_axis.ipynb)

View File

@@ -0,0 +1,65 @@
# 演示寄生轴
创建寄生轴。这些轴将与主体轴共享x比例但在y方向显示不同的比例。
请注意,此方法使用 [parasite_axes](https://matplotlib.org/api/_as_gen/mpl_toolkits.axes_grid1.parasite_axes.html#module-mpl_toolkits.axes_grid1.parasite_axes) 的 [HostAxes](https://matplotlib.org/api/_as_gen/mpl_toolkits.axes_grid1.parasite_axes.HostAxes.html#mpl_toolkits.axes_grid1.parasite_axes.HostAxes) 和 [ParasiteAxes](https://matplotlib.org/api/_as_gen/mpl_toolkits.axes_grid1.parasite_axes.ParasiteAxes.html#mpl_toolkits.axes_grid1.parasite_axes.ParasiteAxes)。 在 [Demo Parasite Axes2](https://matplotlib.org/api/toolkits/axes_grid1.html#toolkit-axesgrid1-index) 示例中可以找到使用[Matplotlib axes_grid1 Toolkit](https://matplotlib.org/api/toolkits/axisartist.html#toolkit-axisartist-index) 和 Matplotlib axisartist Toolkit的替代方法。 使用通常的matplotlib子图的替代方法显示在 [Multiple Yaxis With Spines](https://matplotlib.org/gallery/ticks_and_spines/multiple_yaxis_with_spines.html) 示例中。
![演示寄生轴](https://matplotlib.org/_images/sphx_glr_demo_parasite_axes_001.png)
```python
from mpl_toolkits.axisartist.parasite_axes import HostAxes, ParasiteAxes
import matplotlib.pyplot as plt
fig = plt.figure(1)
host = HostAxes(fig, [0.15, 0.1, 0.65, 0.8])
par1 = ParasiteAxes(host, sharex=host)
par2 = ParasiteAxes(host, sharex=host)
host.parasites.append(par1)
host.parasites.append(par2)
host.set_ylabel("Density")
host.set_xlabel("Distance")
host.axis["right"].set_visible(False)
par1.axis["right"].set_visible(True)
par1.set_ylabel("Temperature")
par1.axis["right"].major_ticklabels.set_visible(True)
par1.axis["right"].label.set_visible(True)
par2.set_ylabel("Velocity")
offset = (60, 0)
new_axisline = par2._grid_helper.new_fixed_axis
par2.axis["right2"] = new_axisline(loc="right", axes=par2, offset=offset)
fig.add_axes(host)
host.set_xlim(0, 2)
host.set_ylim(0, 2)
host.set_xlabel("Distance")
host.set_ylabel("Density")
par1.set_ylabel("Temperature")
p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density")
p2, = par1.plot([0, 1, 2], [0, 3, 2], label="Temperature")
p3, = par2.plot([0, 1, 2], [50, 30, 15], label="Velocity")
par1.set_ylim(0, 4)
par2.set_ylim(1, 65)
host.legend()
host.axis["left"].label.set_color(p1.get_color())
par1.axis["right"].label.set_color(p2.get_color())
par2.axis["right2"].label.set_color(p3.get_color())
plt.show()
```
## 下载这个示例
- [下载python源码: demo_parasite_axes.py](https://matplotlib.org/_downloads/demo_parasite_axes.py)
- [下载Jupyter notebook: demo_parasite_axes.ipynb](https://matplotlib.org/_downloads/demo_parasite_axes.ipynb)

View File

@@ -0,0 +1,58 @@
# 演示寄生轴2
寄生轴的演示。
以下代码是寄生虫轴的示例。 它旨在展示如何在一个单独的图上绘制多个不同的值。 请注意在此示例中par1和par2都调用twinx这意味着两者都直接绑定到x轴。 从那里这两个轴中的每一个可以彼此分开地表现这意味着它们可以从它们自身以及x轴上获取单独的值。
请注意,此方法使用 [parasite_axes](https://matplotlib.org/api/_as_gen/mpl_toolkits.axes_grid1.parasite_axes.html#module-mpl_toolkits.axes_grid1.parasite_axes) 的 [HostAxes](https://matplotlib.org/api/_as_gen/mpl_toolkits.axes_grid1.parasite_axes.HostAxes.html#mpl_toolkits.axes_grid1.parasite_axes.HostAxes) 和 [ParasiteAxes](https://matplotlib.org/api/_as_gen/mpl_toolkits.axes_grid1.parasite_axes.ParasiteAxes.html#mpl_toolkits.axes_grid1.parasite_axes.ParasiteAxes)。 在 [Demo Parasite Axes2](https://matplotlib.org/api/toolkits/axes_grid1.html#toolkit-axesgrid1-index) 示例中可以找到使用[Matplotlib axes_grid1 Toolkit](https://matplotlib.org/api/toolkits/axisartist.html#toolkit-axisartist-index) 和 Matplotlib axisartist Toolkit的替代方法。 使用通常的matplotlib子图的替代方法显示在 [Multiple Yaxis With Spines](https://matplotlib.org/gallery/ticks_and_spines/multiple_yaxis_with_spines.html) 示例中。
![演示寄生轴2](https://matplotlib.org/_images/sphx_glr_demo_parasite_axes2_001.png)
```python
from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA
import matplotlib.pyplot as plt
host = host_subplot(111, axes_class=AA.Axes)
plt.subplots_adjust(right=0.75)
par1 = host.twinx()
par2 = host.twinx()
offset = 60
new_fixed_axis = par2.get_grid_helper().new_fixed_axis
par2.axis["right"] = new_fixed_axis(loc="right",
axes=par2,
offset=(offset, 0))
par1.axis["right"].toggle(all=True)
par2.axis["right"].toggle(all=True)
host.set_xlim(0, 2)
host.set_ylim(0, 2)
host.set_xlabel("Distance")
host.set_ylabel("Density")
par1.set_ylabel("Temperature")
par2.set_ylabel("Velocity")
p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density")
p2, = par1.plot([0, 1, 2], [0, 3, 2], label="Temperature")
p3, = par2.plot([0, 1, 2], [50, 30, 15], label="Velocity")
par1.set_ylim(0, 4)
par2.set_ylim(1, 65)
host.legend()
host.axis["left"].label.set_color(p1.get_color())
par1.axis["right"].label.set_color(p2.get_color())
par2.axis["right"].label.set_color(p3.get_color())
plt.show()
```
## 下载这个示例
- [下载python源码: demo_parasite_axes2.py](https://matplotlib.org/_downloads/demo_parasite_axes2.py)
- [下载Jupyter notebook: demo_parasite_axes2.ipynb](https://matplotlib.org/_downloads/demo_parasite_axes2.ipynb)

View File

@@ -0,0 +1,47 @@
# Ticklabel对齐演示
![Ticklabel对齐演示](https://matplotlib.org/_images/sphx_glr_demo_ticklabel_alignment_001.png)
```python
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as axisartist
def setup_axes(fig, rect):
ax = axisartist.Subplot(fig, rect)
fig.add_subplot(ax)
ax.set_yticks([0.2, 0.8])
ax.set_yticklabels(["short", "loooong"])
ax.set_xticks([0.2, 0.8])
ax.set_xticklabels([r"$\frac{1}{2}\pi$", r"$\pi$"])
return ax
fig = plt.figure(1, figsize=(3, 5))
fig.subplots_adjust(left=0.5, hspace=0.7)
ax = setup_axes(fig, 311)
ax.set_ylabel("ha=right")
ax.set_xlabel("va=baseline")
ax = setup_axes(fig, 312)
ax.axis["left"].major_ticklabels.set_ha("center")
ax.axis["bottom"].major_ticklabels.set_va("top")
ax.set_ylabel("ha=center")
ax.set_xlabel("va=top")
ax = setup_axes(fig, 313)
ax.axis["left"].major_ticklabels.set_ha("left")
ax.axis["bottom"].major_ticklabels.set_va("bottom")
ax.set_ylabel("ha=left")
ax.set_xlabel("va=bottom")
plt.show()
```
## 下载这个示例
- [下载python源码: demo_ticklabel_alignment.py](https://matplotlib.org/_downloads/demo_ticklabel_alignment.py)
- [下载Jupyter notebook: demo_ticklabel_alignment.ipynb](https://matplotlib.org/_downloads/demo_ticklabel_alignment.ipynb)

View File

@@ -0,0 +1,47 @@
# Ticklabel方向演示
![Ticklabel方向演示](https://matplotlib.org/_images/sphx_glr_demo_ticklabel_alignment_001.png)
```python
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as axisartist
def setup_axes(fig, rect):
ax = axisartist.Subplot(fig, rect)
fig.add_subplot(ax)
ax.set_yticks([0.2, 0.8])
ax.set_yticklabels(["short", "loooong"])
ax.set_xticks([0.2, 0.8])
ax.set_xticklabels([r"$\frac{1}{2}\pi$", r"$\pi$"])
return ax
fig = plt.figure(1, figsize=(3, 5))
fig.subplots_adjust(left=0.5, hspace=0.7)
ax = setup_axes(fig, 311)
ax.set_ylabel("ha=right")
ax.set_xlabel("va=baseline")
ax = setup_axes(fig, 312)
ax.axis["left"].major_ticklabels.set_ha("center")
ax.axis["bottom"].major_ticklabels.set_va("top")
ax.set_ylabel("ha=center")
ax.set_xlabel("va=top")
ax = setup_axes(fig, 313)
ax.axis["left"].major_ticklabels.set_ha("left")
ax.axis["bottom"].major_ticklabels.set_va("bottom")
ax.set_ylabel("ha=left")
ax.set_xlabel("va=bottom")
plt.show()
```
## 下载这个示例
- [下载python源码: demo_ticklabel_alignment.py](https://matplotlib.org/_downloads/demo_ticklabel_alignment.py)
- [下载Jupyter notebook: demo_ticklabel_alignment.ipynb](https://matplotlib.org/_downloads/demo_ticklabel_alignment.ipynb)

View File

@@ -0,0 +1,26 @@
# 简单轴方向01
![简单轴方向01](https://matplotlib.org/_images/sphx_glr_simple_axis_direction01_001.png)
```python
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as axisartist
fig = plt.figure(figsize=(4, 2.5))
ax1 = fig.add_subplot(axisartist.Subplot(fig, "111"))
fig.subplots_adjust(right=0.8)
ax1.axis["left"].major_ticklabels.set_axis_direction("top")
ax1.axis["left"].label.set_text("Label")
ax1.axis["right"].label.set_visible(True)
ax1.axis["right"].label.set_text("Label")
ax1.axis["right"].label.set_axis_direction("left")
plt.show()
```
## 下载这个示例
- [下载python源码: simple_axis_direction01.py](https://matplotlib.org/_downloads/simple_axis_direction01.py)
- [下载Jupyter notebook: simple_axis_direction01.ipynb](https://matplotlib.org/_downloads/simple_axis_direction01.ipynb)

View File

@@ -0,0 +1,41 @@
# 简单轴方向03
![简单轴方向03](https://matplotlib.org/_images/sphx_glr_simple_axis_direction03_001.png)
```python
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as axisartist
def setup_axes(fig, rect):
ax = axisartist.Subplot(fig, rect)
fig.add_subplot(ax)
ax.set_yticks([0.2, 0.8])
ax.set_xticks([0.2, 0.8])
return ax
fig = plt.figure(1, figsize=(5, 2))
fig.subplots_adjust(wspace=0.4, bottom=0.3)
ax1 = setup_axes(fig, "121")
ax1.set_xlabel("X-label")
ax1.set_ylabel("Y-label")
ax1.axis[:].invert_ticklabel_direction()
ax2 = setup_axes(fig, "122")
ax2.set_xlabel("X-label")
ax2.set_ylabel("Y-label")
ax2.axis[:].major_ticks.set_tick_out(True)
plt.show()
```
## 下载这个示例
- [下载python源码: simple_axis_direction03.py](https://matplotlib.org/_downloads/simple_axis_direction03.py)
- [下载Jupyter notebook: simple_axis_direction03.ipynb](https://matplotlib.org/_downloads/simple_axis_direction03.ipynb)

View File

@@ -0,0 +1,114 @@
# 简单的轴垫
![简单的轴垫](https://matplotlib.org/_images/sphx_glr_simple_axis_pad_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist.angle_helper as angle_helper
import mpl_toolkits.axisartist.grid_finder as grid_finder
from matplotlib.projections import PolarAxes
from matplotlib.transforms import Affine2D
import mpl_toolkits.axisartist as axisartist
from mpl_toolkits.axisartist.grid_helper_curvelinear import \
GridHelperCurveLinear
def setup_axes(fig, rect):
"""
polar projection, but in a rectangular box.
"""
# see demo_curvelinear_grid.py for details
tr = Affine2D().scale(np.pi/180., 1.) + PolarAxes.PolarTransform()
extreme_finder = angle_helper.ExtremeFinderCycle(20, 20,
lon_cycle=360,
lat_cycle=None,
lon_minmax=None,
lat_minmax=(0, np.inf),
)
grid_locator1 = angle_helper.LocatorDMS(12)
grid_locator2 = grid_finder.MaxNLocator(5)
tick_formatter1 = angle_helper.FormatterDMS()
grid_helper = GridHelperCurveLinear(tr,
extreme_finder=extreme_finder,
grid_locator1=grid_locator1,
grid_locator2=grid_locator2,
tick_formatter1=tick_formatter1
)
ax1 = axisartist.Subplot(fig, rect, grid_helper=grid_helper)
ax1.axis[:].set_visible(False)
fig.add_subplot(ax1)
ax1.set_aspect(1.)
ax1.set_xlim(-5, 12)
ax1.set_ylim(-5, 10)
return ax1
def add_floating_axis1(ax1):
ax1.axis["lat"] = axis = ax1.new_floating_axis(0, 30)
axis.label.set_text(r"$\theta = 30^{\circ}$")
axis.label.set_visible(True)
return axis
def add_floating_axis2(ax1):
ax1.axis["lon"] = axis = ax1.new_floating_axis(1, 6)
axis.label.set_text(r"$r = 6$")
axis.label.set_visible(True)
return axis
fig = plt.figure(1, figsize=(9, 3.))
fig.clf()
fig.subplots_adjust(left=0.01, right=0.99, bottom=0.01, top=0.99,
wspace=0.01, hspace=0.01)
def ann(ax1, d):
if plt.rcParams["text.usetex"]:
d = d.replace("_", r"\_")
ax1.annotate(d, (0.5, 1), (5, -5),
xycoords="axes fraction", textcoords="offset points",
va="top", ha="center")
ax1 = setup_axes(fig, rect=141)
axis = add_floating_axis1(ax1)
ann(ax1, r"default")
ax1 = setup_axes(fig, rect=142)
axis = add_floating_axis1(ax1)
axis.major_ticklabels.set_pad(10)
ann(ax1, r"ticklabels.set_pad(10)")
ax1 = setup_axes(fig, rect=143)
axis = add_floating_axis1(ax1)
axis.label.set_pad(20)
ann(ax1, r"label.set_pad(20)")
ax1 = setup_axes(fig, rect=144)
axis = add_floating_axis1(ax1)
axis.major_ticks.set_tick_out(True)
ann(ax1, "ticks.set_tick_out(True)")
plt.show()
```
## 下载这个示例
- [下载python源码: simple_axis_pad.py](https://matplotlib.org/_downloads/simple_axis_pad.py)
- [下载Jupyter notebook: simple_axis_pad.ipynb](https://matplotlib.org/_downloads/simple_axis_pad.ipynb)

View File

@@ -0,0 +1,32 @@
# 简单的Axisartist1
![简单的Axisartist1](https://matplotlib.org/_images/sphx_glr_simple_axisartist1_001.png)
```python
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as AA
fig = plt.figure(1)
fig.subplots_adjust(right=0.85)
ax = AA.Subplot(fig, 1, 1, 1)
fig.add_subplot(ax)
# make some axis invisible
ax.axis["bottom", "top", "right"].set_visible(False)
# make an new axis along the first axis axis (x-axis) which pass
# through y=0.
ax.axis["y=0"] = ax.new_floating_axis(nth_coord=0, value=0,
axis_direction="bottom")
ax.axis["y=0"].toggle(all=True)
ax.axis["y=0"].label.set_text("y = 0")
ax.set_ylim(-2, 4)
plt.show()
```
## 下载这个示例
- [下载python源码: simple_axisartist1.py](https://matplotlib.org/_downloads/simple_axisartist1.py)
- [下载Jupyter notebook: simple_axisartist1.ipynb](https://matplotlib.org/_downloads/simple_axisartist1.ipynb)

View File

@@ -0,0 +1,45 @@
# 简单的轴线
![简单的轴线](https://matplotlib.org/_images/sphx_glr_simple_axisline_001.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axisartist.axislines import SubplotZero
fig = plt.figure(1)
fig.subplots_adjust(right=0.85)
ax = SubplotZero(fig, 1, 1, 1)
fig.add_subplot(ax)
# make right and top axis invisible
ax.axis["right"].set_visible(False)
ax.axis["top"].set_visible(False)
# make xzero axis (horizontal axis line through y=0) visible.
ax.axis["xzero"].set_visible(True)
ax.axis["xzero"].label.set_text("Axis Zero")
ax.set_ylim(-2, 4)
ax.set_xlabel("Label X")
ax.set_ylabel("Label Y")
# or
#ax.axis["bottom"].label.set_text("Label X")
#ax.axis["left"].label.set_text("Label Y")
# make new (right-side) yaxis, but with some offset
offset = (20, 0)
new_axisline = ax.get_grid_helper().new_fixed_axis
ax.axis["right2"] = new_axisline(loc="right", offset=offset, axes=ax)
ax.axis["right2"].label.set_text("Label Y2")
ax.plot([-2, 3, 2])
plt.show()
```
## 下载这个示例
- [下载python源码: simple_axisline.py](https://matplotlib.org/_downloads/simple_axisline.py)
- [下载Jupyter notebook: simple_axisline.ipynb](https://matplotlib.org/_downloads/simple_axisline.ipynb)

View File

@@ -0,0 +1,34 @@
# 简单的轴线2
![简单的轴线2](https://matplotlib.org/_images/sphx_glr_simple_axisline2_001.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axisartist.axislines import SubplotZero
import numpy as np
fig = plt.figure(1, (4, 3))
# a subplot with two additional axis, "xzero" and "yzero". "xzero" is
# y=0 line, and "yzero" is x=0 line.
ax = SubplotZero(fig, 1, 1, 1)
fig.add_subplot(ax)
# make xzero axis (horizontal axis line through y=0) visible.
ax.axis["xzero"].set_visible(True)
ax.axis["xzero"].label.set_text("Axis Zero")
# make other axis (bottom, top, right) invisible.
for n in ["bottom", "top", "right"]:
ax.axis[n].set_visible(False)
xx = np.arange(0, 2*np.pi, 0.01)
ax.plot(xx, np.sin(xx))
plt.show()
```
## 下载这个示例
- [下载python源码: simple_axisline2.py](https://matplotlib.org/_downloads/simple_axisline2.py)
- [下载Jupyter notebook: simple_axisline2.ipynb](https://matplotlib.org/_downloads/simple_axisline2.ipynb)

View File

@@ -0,0 +1,23 @@
# 简单的轴线3
![简单的轴线3](https://matplotlib.org/_images/sphx_glr_simple_axisline3_001.png)
```python
import matplotlib.pyplot as plt
from mpl_toolkits.axisartist.axislines import Subplot
fig = plt.figure(1, (3, 3))
ax = Subplot(fig, 111)
fig.add_subplot(ax)
ax.axis["right"].set_visible(False)
ax.axis["top"].set_visible(False)
plt.show()
```
## 下载这个示例
- [下载python源码: simple_axisline3.py](https://matplotlib.org/_downloads/simple_axisline3.py)
- [下载Jupyter notebook: simple_axisline3.ipynb](https://matplotlib.org/_downloads/simple_axisline3.ipynb)

View File

@@ -0,0 +1,40 @@
# 通过y-value绘制颜色
使用掩码数组以y值绘制具有不同颜色的线。
```python
import numpy as np
import matplotlib.pyplot as plt
t = np.arange(0.0, 2.0, 0.01)
s = np.sin(2 * np.pi * t)
upper = 0.77
lower = -0.77
supper = np.ma.masked_where(s < upper, s)
slower = np.ma.masked_where(s > lower, s)
smiddle = np.ma.masked_where(np.logical_or(s < lower, s > upper), s)
fig, ax = plt.subplots()
ax.plot(t, smiddle, t, slower, t, supper)
plt.show()
```
![y-value绘制颜色示例](https://matplotlib.org/_images/sphx_glr_color_by_yvalue_001.png)
## 参考
此示例中显示了以下函数,方法,类和模块的使用:
```python
import matplotlib
matplotlib.axes.Axes.plot
matplotlib.pyplot.plot
```
## 下载这个示例
- [下载python源码: color_by_yvalue.py](https://matplotlib.org/_downloads/color_by_yvalue.py)
- [下载Jupyter notebook: color_by_yvalue.ipynb](https://matplotlib.org/_downloads/color_by_yvalue.ipynb)

View File

@@ -0,0 +1,60 @@
# 默认属性循环中的颜色
显示默认prop_cycle中的颜色该颜色是从[rc参数](https://matplotlib.org/tutorials/introductory/customizing.html)中获取的。
```python
import numpy as np
import matplotlib.pyplot as plt
prop_cycle = plt.rcParams['axes.prop_cycle']
colors = prop_cycle.by_key()['color']
lwbase = plt.rcParams['lines.linewidth']
thin = lwbase / 2
thick = lwbase * 3
fig, axs = plt.subplots(nrows=2, ncols=2, sharex=True, sharey=True)
for icol in range(2):
if icol == 0:
lwx, lwy = thin, lwbase
else:
lwx, lwy = lwbase, thick
for irow in range(2):
for i, color in enumerate(colors):
axs[irow, icol].axhline(i, color=color, lw=lwx)
axs[irow, icol].axvline(i, color=color, lw=lwy)
axs[1, icol].set_facecolor('k')
axs[1, icol].xaxis.set_ticks(np.arange(0, 10, 2))
axs[0, icol].set_title('line widths (pts): %g, %g' % (lwx, lwy),
fontsize='medium')
for irow in range(2):
axs[irow, 0].yaxis.set_ticks(np.arange(0, 10, 2))
fig.suptitle('Colors in the default prop_cycle', fontsize='large')
plt.show()
```
![默认属性循环中的颜色示例](https://matplotlib.org/_images/sphx_glr_color_cycle_default_001.png)
## 参考
此示例中显示了以下函数,方法,类和模块的使用:
```python
import matplotlib
matplotlib.axes.Axes.axhline
matplotlib.axes.Axes.axvline
matplotlib.pyplot.axhline
matplotlib.pyplot.axvline
matplotlib.axes.Axes.set_facecolor
matplotlib.figure.Figure.suptitle
```
## 下载这个示例
- [下载python源码: color_cycle_default.py](https://matplotlib.org/_downloads/color_cycle_default.py)
- [下载Jupyter notebook: color_cycle_default.ipynb](https://matplotlib.org/_downloads/color_cycle_default.ipynb)

View File

@@ -0,0 +1,54 @@
# 用cycler定型
演示自定义特性-循环设置以控制多行绘制的颜色和其他样式特性。
此示例演示了两种不同的API
```python
from cycler import cycler
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2 * np.pi)
offsets = np.linspace(0, 2*np.pi, 4, endpoint=False)
# Create array with shifted-sine curve along each column
yy = np.transpose([np.sin(x + phi) for phi in offsets])
# 1. Setting prop cycle on default rc parameter
plt.rc('lines', linewidth=4)
plt.rc('axes', prop_cycle=(cycler(color=['r', 'g', 'b', 'y']) +
cycler(linestyle=['-', '--', ':', '-.'])))
fig, (ax0, ax1) = plt.subplots(nrows=2, constrained_layout=True)
ax0.plot(yy)
ax0.set_title('Set default color cycle to rgby')
# 2. Define prop cycle for single set of axes
# For the most general use-case, you can provide a cycler to
# `.set_prop_cycle`.
# Here, we use the convenient shortcut that we can alternatively pass
# one or more properties as keyword arguements. This creates and sets
# a cycler iterating simultaneously over all properties.
ax1.set_prop_cycle(color=['c', 'm', 'y', 'k'], lw=[1, 2, 3, 4])
ax1.plot(yy)
ax1.set_title('Set axes color cycle to cmyk')
plt.show()
```
![cycler定型示例](https://matplotlib.org/_images/sphx_glr_color_cycler_001.png)
## 参考
此示例中显示了以下函数,方法,类和模块的使用:
```python
import matplotlib
matplotlib.axes.Axes.plot
matplotlib.axes.Axes.set_prop_cycle
```
## 下载这个示例
- [下载python源码: color_cycler.py](https://matplotlib.org/_downloads/color_cycler.py)
- [下载Jupyter notebook: color_cycler.ipynb](https://matplotlib.org/_downloads/color_cycler.ipynb)

View File

@@ -0,0 +1,68 @@
# 基本颜色演示
Matplotlib为您提供了8种指定颜色的方法
1. 在[0, 1]中的浮点值的RGB或RGBA元组例如 (0.1, 0.2, 0.5) 或 (0.1, 0.2, 0.5, 0.3)。RGBA是红色绿色蓝色Alpha的缩写;
1. 十六进制RGB或RGBA字符串 ``(例如: '#0F0F0F' 或者 '#0F0F0F0F')``
1. [0, 1]中浮点值的字符串表示,包括灰度级(例如,'0.5'
1. 单字母字符串,例如这些其中之一:``{'b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'}``;
1. 一个 X11/CSS4 ("html") 颜色名称, 例如:"blue";
1. 来自[xkcd的颜色调研](https://xkcd.com/color/rgb/)的名称,前缀为 'xkcd:' (例如“xkcd:sky blue”)
1. 一个 “Cn” 颜色规范,即 'C' 后跟一个数字,这是默认属性循环的索引(``matplotlib.rcParams['axes.prop_cycle']``; 索引在艺术家对象创建时发生,如果循环不包括颜色,则默认为黑色。
1. 其中一个 ``{'tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan'}``,它们是'tab10'分类调色板中的Tableau颜色这是默认的颜色循环;
有关matplotlib中颜色的更多信息请参阅
- [指定颜色](https://matplotlib.org/tutorials/colors/colors.html)教程;
- [matplotlib.colors](https://matplotlib.org/api/colors_api.html#module-matplotlib.colors) API;
- [可视化命名颜色](https://matplotlib.org/gallery/color/named_colors.html)示例。
```python
import matplotlib.pyplot as plt
import numpy as np
t = np.linspace(0.0, 2.0, 201)
s = np.sin(2 * np.pi * t)
# 1) RGB tuple:
fig, ax = plt.subplots(facecolor=(.18, .31, .31))
# 2) hex string:
ax.set_facecolor('#eafff5')
# 3) gray level string:
ax.set_title('Voltage vs. time chart', color='0.7')
# 4) single letter color string
ax.set_xlabel('time (s)', color='c')
# 5) a named color:
ax.set_ylabel('voltage (mV)', color='peachpuff')
# 6) a named xkcd color:
ax.plot(t, s, 'xkcd:crimson')
# 7) Cn notation:
ax.plot(t, .7*s, color='C4', linestyle='--')
# 8) tab notation:
ax.tick_params(labelcolor='tab:orange')
plt.show()
```
![基本颜色演示](https://matplotlib.org/_images/sphx_glr_color_demo_001.png)
## 参考
此示例中显示了以下函数,方法,类和模块的使用:
```python
import matplotlib
matplotlib.colors
matplotlib.axes.Axes.plot
matplotlib.axes.Axes.set_facecolor
matplotlib.axes.Axes.set_title
matplotlib.axes.Axes.set_xlabel
matplotlib.axes.Axes.set_ylabel
matplotlib.axes.Axes.tick_params
```
## 下载这个示例
- [下载python源码: color_demo.py](https://matplotlib.org/_downloads/color_demo.py)
- [下载Jupyter notebook: color_demo.ipynb](https://matplotlib.org/_downloads/color_demo.ipynb)

View File

@@ -0,0 +1,63 @@
# 颜色条
通过指定可映射对象(此处为[imshow](https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.imshow.html#matplotlib.axes.Axes.imshow)返回的 [AxesImage](https://matplotlib.org/api/image_api.html#matplotlib.image.AxesImage) )和要将颜色条附加到的轴来使用 [colorbar](https://matplotlib.org/api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure.colorbar)。
```python
import numpy as np
import matplotlib.pyplot as plt
# setup some generic data
N = 37
x, y = np.mgrid[:N, :N]
Z = (np.cos(x*0.2) + np.sin(y*0.3))
# mask out the negative and positive values, respectively
Zpos = np.ma.masked_less(Z, 0)
Zneg = np.ma.masked_greater(Z, 0)
fig, (ax1, ax2, ax3) = plt.subplots(figsize=(13, 3), ncols=3)
# plot just the positive data and save the
# color "mappable" object returned by ax1.imshow
pos = ax1.imshow(Zpos, cmap='Blues', interpolation='none')
# add the colorbar using the figure's method,
# telling which mappable we're talking about and
# which axes object it should be near
fig.colorbar(pos, ax=ax1)
# repeat everything above for the negative data
neg = ax2.imshow(Zneg, cmap='Reds_r', interpolation='none')
fig.colorbar(neg, ax=ax2)
# Plot both positive and negative values betwen +/- 1.2
pos_neg_clipped = ax3.imshow(Z, cmap='RdBu', vmin=-1.2, vmax=1.2,
interpolation='none')
# Add minorticks on the colorbar to make it easy to read the
# values off the colorbar.
cbar = fig.colorbar(pos_neg_clipped, ax=ax3, extend='both')
cbar.minorticks_on()
plt.show()
```
![颜色条示例](https://matplotlib.org/_images/sphx_glr_colorbar_basics_001.png)
## 参考
此示例中显示了以下函数,方法,类和模块的使用:
```python
import matplotlib
import matplotlib.colorbar
matplotlib.axes.Axes.imshow
matplotlib.pyplot.imshow
matplotlib.figure.Figure.colorbar
matplotlib.pyplot.colorbar
matplotlib.colorbar.Colorbar.minorticks_on
matplotlib.colorbar.Colorbar.minorticks_off
```
## 下载这个示例
- [下载python源码: colorbar_basics.py](https://matplotlib.org/_downloads/colorbar_basics.py)
- [下载Jupyter notebook: colorbar_basics.ipynb](https://matplotlib.org/_downloads/colorbar_basics.ipynb)

View File

@@ -0,0 +1,96 @@
# Colormap参考
Matplotlib附带的色彩映射参考。
通过将 ``_r`` 附加到名称(例如,``viridis_r``),可以获得每个这些颜色映射的反转版本。
请参阅在[Matplotlib中选择Colormaps](https://matplotlib.org/tutorials/colors/colormaps.html)以深入讨论色彩映射包括colorblind-friendlyliness。
```python
import numpy as np
import matplotlib.pyplot as plt
cmaps = [('Perceptually Uniform Sequential', [
'viridis', 'plasma', 'inferno', 'magma', 'cividis']),
('Sequential', [
'Greys', 'Purples', 'Blues', 'Greens', 'Oranges', 'Reds',
'YlOrBr', 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu',
'GnBu', 'PuBu', 'YlGnBu', 'PuBuGn', 'BuGn', 'YlGn']),
('Sequential (2)', [
'binary', 'gist_yarg', 'gist_gray', 'gray', 'bone', 'pink',
'spring', 'summer', 'autumn', 'winter', 'cool', 'Wistia',
'hot', 'afmhot', 'gist_heat', 'copper']),
('Diverging', [
'PiYG', 'PRGn', 'BrBG', 'PuOr', 'RdGy', 'RdBu',
'RdYlBu', 'RdYlGn', 'Spectral', 'coolwarm', 'bwr', 'seismic']),
('Cyclic', ['twilight', 'twilight_shifted', 'hsv']),
('Qualitative', [
'Pastel1', 'Pastel2', 'Paired', 'Accent',
'Dark2', 'Set1', 'Set2', 'Set3',
'tab10', 'tab20', 'tab20b', 'tab20c']),
('Miscellaneous', [
'flag', 'prism', 'ocean', 'gist_earth', 'terrain', 'gist_stern',
'gnuplot', 'gnuplot2', 'CMRmap', 'cubehelix', 'brg',
'gist_rainbow', 'rainbow', 'jet', 'nipy_spectral', 'gist_ncar'])]
gradient = np.linspace(0, 1, 256)
gradient = np.vstack((gradient, gradient))
def plot_color_gradients(cmap_category, cmap_list):
# Create figure and adjust figure height to number of colormaps
nrows = len(cmap_list)
figh = 0.35 + 0.15 + (nrows + (nrows-1)*0.1)*0.22
fig, axes = plt.subplots(nrows=nrows, figsize=(6.4, figh))
fig.subplots_adjust(top=1-.35/figh, bottom=.15/figh, left=0.2, right=0.99)
axes[0].set_title(cmap_category + ' colormaps', fontsize=14)
for ax, name in zip(axes, cmap_list):
ax.imshow(gradient, aspect='auto', cmap=plt.get_cmap(name))
ax.text(-.01, .5, name, va='center', ha='right', fontsize=10,
transform=ax.transAxes)
# Turn off *all* ticks & spines, not just the ones with colormaps.
for ax in axes:
ax.set_axis_off()
for cmap_category, cmap_list in cmaps:
plot_color_gradients(cmap_category, cmap_list)
plt.show()
```
![Colormap参考示例](https://matplotlib.org/_images/sphx_glr_colormap_reference_001.png)
![Colormap参考示例2](https://matplotlib.org/_images/sphx_glr_colormap_reference_002.png)
![Colormap参考示例3](https://matplotlib.org/_images/sphx_glr_colormap_reference_003.png)
![Colormap参考示例4](https://matplotlib.org/_images/sphx_glr_colormap_reference_004.png)
![Colormap参考示例5](https://matplotlib.org/_images/sphx_glr_colormap_reference_005.png)
![Colormap参考示例6](https://matplotlib.org/_images/sphx_glr_colormap_reference_006.png)
![Colormap参考示例7](https://matplotlib.org/_images/sphx_glr_colormap_reference_007.png)
## 参考
此示例中显示了以下函数,方法,类和模块的使用:
```python
import matplotlib
matplotlib.colors
matplotlib.axes.Axes.imshow
matplotlib.figure.Figure.text
matplotlib.axes.Axes.set_axis_off
```
## 下载这个示例
- [下载python源码: colormap_reference.py](https://matplotlib.org/_downloads/colormap_reference.py)
- [下载Jupyter notebook: colormap_reference.ipynb](https://matplotlib.org/_downloads/colormap_reference.ipynb)

View File

@@ -0,0 +1,229 @@
# 从颜色列表创建颜色映射
有关创建和操作色彩映射的更多详细信息,请参阅[在Matplotlib中创建色彩映射](https://matplotlib.org/tutorials/colors/colormap-manipulation.html)。
可以使用LinearSegmentedColormap的[from_list()](https://matplotlib.org/api/_as_gen/matplotlib.colors.LinearSegmentedColormap.html#matplotlib.colors.LinearSegmentedColormap.from_list)方法从颜色列表创建[颜色映射](https://matplotlib.org/tutorials/colors/colormaps.html)。您必须传递一个RGB元组列表用于定义从0到1的颜色混合。
## 创建自定义色彩映射
也可以为色彩映射创建自定义映射。 这是通过创建字典来实现的该字典指定RGB通道如何从cmap的一端变为另一端。
示例假设您希望红色在下半部分从0增加到1绿色在中间半部分增加到相同而在上半部分则为蓝色。 然后你会用:
```python
cdict = {'red': ((0.0, 0.0, 0.0),
(0.5, 1.0, 1.0),
(1.0, 1.0, 1.0)),
'green': ((0.0, 0.0, 0.0),
(0.25, 0.0, 0.0),
(0.75, 1.0, 1.0),
(1.0, 1.0, 1.0)),
'blue': ((0.0, 0.0, 0.0),
(0.5, 0.0, 0.0),
(1.0, 1.0, 1.0))}
```
如果在这个例子中rg和b组件中没有不连续性那么它很简单上面每个元组的第二个和第三个元素是相同的 - 称之为“y”。 第一个元素“x”定义了0到1整个范围内的插值间隔它必须跨越整个范围。换句话说x的值将0到1范围划分为一组段并且y给出每个段的端点颜色值。
现在考虑绿色。cdict['green']表示对于0 <= x <= 0.25y为零; 没有绿色。0.25 < x <= 0.75y从0到1线性变化.x > 0.75y保持为1全绿色。
如果存在不连续性则会更复杂一些。将给定颜色的cdict条目中每行中的3个元素标记为x, y0, y1。然后对于x[i] 和 x[i + 1]之间的x值在 y1[i] 和 y0[i + 1] 之间内插颜色值。
回到指南里的例子看看cdict['red']; 因为y0= y1它表示对于x从0到0.5红色从0增加到1但随后它向下跳跃因此对于x从0.5到1红色从0.7增加到1.绿色斜坡从0开始 当x从0变为0.5时变为1然后跳回0当x从0.5变为1时斜坡变回1
```python
row i: x y0 y1
/
/
row i+1: x y0 y1
```
以上是试图表明对于x[i]到 x[i + 1] 范围内的x插值在 y1[i] 和 y0[i + 1] 之间。因此永远不会使用y0[0] 和 y1[-1]。
```python
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
# Make some illustrative fake data:
x = np.arange(0, np.pi, 0.1)
y = np.arange(0, 2 * np.pi, 0.1)
X, Y = np.meshgrid(x, y)
Z = np.cos(X) * np.sin(Y) * 10
```
--- 列表中的色彩映射 ---
```python
colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1)] # R -> G -> B
n_bins = [3, 6, 10, 100] # Discretizes the interpolation into bins
cmap_name = 'my_list'
fig, axs = plt.subplots(2, 2, figsize=(6, 9))
fig.subplots_adjust(left=0.02, bottom=0.06, right=0.95, top=0.94, wspace=0.05)
for n_bin, ax in zip(n_bins, axs.ravel()):
# Create the colormap
cm = LinearSegmentedColormap.from_list(
cmap_name, colors, N=n_bin)
# Fewer bins will result in "coarser" colomap interpolation
im = ax.imshow(Z, interpolation='nearest', origin='lower', cmap=cm)
ax.set_title("N bins: %s" % n_bin)
fig.colorbar(im, ax=ax)
```
![从颜色列表创建颜色映射示例](https://matplotlib.org/_images/sphx_glr_custom_cmap_001.png)
--- 自定义色彩映射 ---
```python
cdict1 = {'red': ((0.0, 0.0, 0.0),
(0.5, 0.0, 0.1),
(1.0, 1.0, 1.0)),
'green': ((0.0, 0.0, 0.0),
(1.0, 0.0, 0.0)),
'blue': ((0.0, 0.0, 1.0),
(0.5, 0.1, 0.0),
(1.0, 0.0, 0.0))
}
cdict2 = {'red': ((0.0, 0.0, 0.0),
(0.5, 0.0, 1.0),
(1.0, 0.1, 1.0)),
'green': ((0.0, 0.0, 0.0),
(1.0, 0.0, 0.0)),
'blue': ((0.0, 0.0, 0.1),
(0.5, 1.0, 0.0),
(1.0, 0.0, 0.0))
}
cdict3 = {'red': ((0.0, 0.0, 0.0),
(0.25, 0.0, 0.0),
(0.5, 0.8, 1.0),
(0.75, 1.0, 1.0),
(1.0, 0.4, 1.0)),
'green': ((0.0, 0.0, 0.0),
(0.25, 0.0, 0.0),
(0.5, 0.9, 0.9),
(0.75, 0.0, 0.0),
(1.0, 0.0, 0.0)),
'blue': ((0.0, 0.0, 0.4),
(0.25, 1.0, 1.0),
(0.5, 1.0, 0.8),
(0.75, 0.0, 0.0),
(1.0, 0.0, 0.0))
}
# Make a modified version of cdict3 with some transparency
# in the middle of the range.
cdict4 = {**cdict3,
'alpha': ((0.0, 1.0, 1.0),
# (0.25,1.0, 1.0),
(0.5, 0.3, 0.3),
# (0.75,1.0, 1.0),
(1.0, 1.0, 1.0)),
}
```
现在我们将使用此示例来说明处理自定义色彩映射的3种方法。首先最直接和明确的
```python
blue_red1 = LinearSegmentedColormap('BlueRed1', cdict1)
```
其次显式创建地图并注册它。与第一种方法一样此方法适用于任何类型的Colormap而不仅仅是LinearSegmentedColormap
```python
blue_red2 = LinearSegmentedColormap('BlueRed2', cdict2)
plt.register_cmap(cmap=blue_red2)
```
第三仅对于LinearSegmentedColormap将所有内容保留为register_cmap
```python
plt.register_cmap(name='BlueRed3', data=cdict3) # optional lut kwarg
plt.register_cmap(name='BlueRedAlpha', data=cdict4)
```
制作图:
```python
fig, axs = plt.subplots(2, 2, figsize=(6, 9))
fig.subplots_adjust(left=0.02, bottom=0.06, right=0.95, top=0.94, wspace=0.05)
# Make 4 subplots:
im1 = axs[0, 0].imshow(Z, interpolation='nearest', cmap=blue_red1)
fig.colorbar(im1, ax=axs[0, 0])
cmap = plt.get_cmap('BlueRed2')
im2 = axs[1, 0].imshow(Z, interpolation='nearest', cmap=cmap)
fig.colorbar(im2, ax=axs[1, 0])
# Now we will set the third cmap as the default. One would
# not normally do this in the middle of a script like this;
# it is done here just to illustrate the method.
plt.rcParams['image.cmap'] = 'BlueRed3'
im3 = axs[0, 1].imshow(Z, interpolation='nearest')
fig.colorbar(im3, ax=axs[0, 1])
axs[0, 1].set_title("Alpha = 1")
# Or as yet another variation, we can replace the rcParams
# specification *before* the imshow with the following *after*
# imshow.
# This sets the new default *and* sets the colormap of the last
# image-like item plotted via pyplot, if any.
#
# Draw a line with low zorder so it will be behind the image.
axs[1, 1].plot([0, 10 * np.pi], [0, 20 * np.pi], color='c', lw=20, zorder=-1)
im4 = axs[1, 1].imshow(Z, interpolation='nearest')
fig.colorbar(im4, ax=axs[1, 1])
# Here it is: changing the colormap for the current image and its
# colorbar after they have been plotted.
im4.set_cmap('BlueRedAlpha')
axs[1, 1].set_title("Varying alpha")
#
fig.suptitle('Custom Blue-Red colormaps', fontsize=16)
fig.subplots_adjust(top=0.9)
plt.show()
```
![从颜色列表创建颜色映射示例2](https://matplotlib.org/_images/sphx_glr_custom_cmap_002.png)
### 参考
此示例中显示了以下函数,方法,类和模块的使用:
```python
import matplotlib
matplotlib.axes.Axes.imshow
matplotlib.pyplot.imshow
matplotlib.figure.Figure.colorbar
matplotlib.pyplot.colorbar
matplotlib.colors
matplotlib.colors.LinearSegmentedColormap
matplotlib.colors.LinearSegmentedColormap.from_list
matplotlib.cm
matplotlib.cm.ScalarMappable.set_cmap
matplotlib.pyplot.register_cmap
matplotlib.cm.register_cmap
```
## 下载这个示例
- [下载python源码: custom_cmap.py](https://matplotlib.org/_downloads/custom_cmap.py)
- [下载Jupyter notebook: custom_cmap.ipynb](https://matplotlib.org/_downloads/custom_cmap.ipynb)

View File

@@ -0,0 +1,3 @@
# 颜色相关示例
有关matplotlib中可用的色彩映射的更深入信息及其属性的说明请参阅[colormaps教程](https://matplotlib.org/tutorials/index.html#tutorials-colors)。

View File

@@ -0,0 +1,106 @@
# 可视化命名颜色
这绘制了matplotlib中支持的命名颜色列表。 请注意,也支持[xkcd颜色](https://matplotlib.org/tutorials/colors/colors.html#xkcd-colors),但为简洁起见,此处未列出。
有关matplotlib中颜色的更多信息请参阅
- [指定颜色](https://matplotlib.org/tutorials/colors/colors.html)教程;
- [matplotlib.colors](https://matplotlib.org/api/colors_api.html#module-matplotlib.colors) API;
- [颜色演示](https://matplotlib.org/gallery/color/color_demo.html)。
```python
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
def plot_colortable(colors, title, sort_colors=True, emptycols=0):
cell_width = 212
cell_height = 22
swatch_width = 48
margin = 12
topmargin = 40
# Sort colors by hue, saturation, value and name.
by_hsv = ((tuple(mcolors.rgb_to_hsv(mcolors.to_rgba(color)[:3])), name)
for name, color in colors.items())
if sort_colors is True:
by_hsv = sorted(by_hsv)
names = [name for hsv, name in by_hsv]
n = len(names)
ncols = 4 - emptycols
nrows = n // ncols + int(n % ncols > 0)
width = cell_width * 4 + 2 * margin
height = cell_height * nrows + margin + topmargin
dpi = 72
fig, ax = plt.subplots(figsize=(width / dpi, height / dpi), dpi=dpi)
fig.subplots_adjust(margin/width, margin/height,
(width-margin)/width, (height-topmargin)/height)
ax.set_xlim(0, cell_width * 4)
ax.set_ylim(cell_height * (nrows-0.5), -cell_height/2.)
ax.yaxis.set_visible(False)
ax.xaxis.set_visible(False)
ax.set_axis_off()
ax.set_title(title, fontsize=24, loc="left", pad=10)
for i, name in enumerate(names):
row = i % nrows
col = i // nrows
y = row * cell_height
swatch_start_x = cell_width * col
swatch_end_x = cell_width * col + swatch_width
text_pos_x = cell_width * col + swatch_width + 7
ax.text(text_pos_x, y, name, fontsize=14,
horizontalalignment='left',
verticalalignment='center')
ax.hlines(y, swatch_start_x, swatch_end_x,
color=colors[name], linewidth=18)
return fig
plot_colortable(mcolors.BASE_COLORS, "Base Colors",
sort_colors=False, emptycols=1)
plot_colortable(mcolors.TABLEAU_COLORS, "Tableau Palette",
sort_colors=False, emptycols=2)
#sphinx_gallery_thumbnail_number = 3
plot_colortable(mcolors.CSS4_COLORS, "CSS Colors")
# Optionally plot the XKCD colors (Caution: will produce large figure)
#xkcd_fig = plot_colortable(mcolors.XKCD_COLORS, "XKCD Colors")
#xkcd_fig.savefig("XKCD_Colors.png")
plt.show()
```
![可视化命名颜色示例](https://matplotlib.org/_images/sphx_glr_named_colors_001.png)
![可视化命名颜色示例2](https://matplotlib.org/_images/sphx_glr_named_colors_002.png)
![可视化命名颜色示例3](https://matplotlib.org/_images/sphx_glr_named_colors_003.png)
## 参考
此示例中显示了以下函数,方法,类和模块的使用:
```python
import matplotlib
matplotlib.colors
matplotlib.colors.rgb_to_hsv
matplotlib.colors.to_rgba
matplotlib.figure.Figure.get_size_inches
matplotlib.figure.Figure.subplots_adjust
matplotlib.axes.Axes.text
matplotlib.axes.Axes.hlines
```
## 下载这个示例
- [下载python源码: named_colors.py](https://matplotlib.org/_downloads/named_colors.py)
- [下载Jupyter notebook: named_colors.ipynb](https://matplotlib.org/_downloads/named_colors.ipynb)

View File

@@ -0,0 +1,4 @@
# 所有示例的下载
- [下载python源码: tutorials_python.py](https://matplotlib.org/_downloads/1e213ff4bcc6ccf3128b453a862c04d2/tutorials_python.zip)
- [下载Jupyter notebook: tutorials_jupyter.ipynb](https://matplotlib.org/_downloads/535f1c08124c14d72d66ebe258383fbe/tutorials_jupyter.zip)

View File

@@ -0,0 +1,24 @@
# 关闭事件
显示图形关闭时发生的连接事件的示例。
![关闭事件示例](https://matplotlib.org/_images/sphx_glr_close_event_001.png)
```python
import matplotlib.pyplot as plt
def handle_close(evt):
print('Closed Figure!')
fig = plt.figure()
fig.canvas.mpl_connect('close_event', handle_close)
plt.text(0.35, 0.5, 'Close Me!', dict(size=30))
plt.show()
```
## 下载这个示例
- [下载python源码: close_event.py](https://matplotlib.org/_downloads/close_event.py)
- [下载Jupyter notebook: close_event.ipynb](https://matplotlib.org/_downloads/close_event.ipynb)

View File

@@ -0,0 +1,48 @@
# Coords 演示
如何通过连接到移动和单击事件来与绘图画布交互的示例
![Coords 演示](https://matplotlib.org/_images/sphx_glr_coords_demo_001.png)
```python
import sys
import matplotlib.pyplot as plt
import numpy as np
t = np.arange(0.0, 1.0, 0.01)
s = np.sin(2 * np.pi * t)
fig, ax = plt.subplots()
ax.plot(t, s)
def on_move(event):
# get the x and y pixel coords
x, y = event.x, event.y
if event.inaxes:
ax = event.inaxes # the axes instance
print('data coords %f %f' % (event.xdata, event.ydata))
def on_click(event):
# get the x and y coords, flip y from top to bottom
x, y = event.x, event.y
if event.button == 1:
if event.inaxes is not None:
print('data coords %f %f' % (event.xdata, event.ydata))
binding_id = plt.connect('motion_notify_event', on_move)
plt.connect('button_press_event', on_click)
if "test_disconnect" in sys.argv:
print("disconnecting console coordinate printout...")
plt.disconnect(binding_id)
plt.show()
```
## 下载这个示例
- [下载python源码: coords_demo.py](https://matplotlib.org/_downloads/coords_demo.py)
- [下载Jupyter notebook: coords_demo.ipynb](https://matplotlib.org/_downloads/coords_demo.ipynb)

View File

@@ -0,0 +1,105 @@
# 数据浏览器
在多个画布之间连接数据。
此示例介绍了如何与多个画布交互数据。这样,您可以选择并突出显示一个轴上的点,并在另一个轴上生成该点的数据。
![数据浏览器示例](https://matplotlib.org/_images/sphx_glr_data_browser_001.png)
```python
import numpy as np
class PointBrowser(object):
"""
Click on a point to select and highlight it -- the data that
generated the point will be shown in the lower axes. Use the 'n'
and 'p' keys to browse through the next and previous points
"""
def __init__(self):
self.lastind = 0
self.text = ax.text(0.05, 0.95, 'selected: none',
transform=ax.transAxes, va='top')
self.selected, = ax.plot([xs[0]], [ys[0]], 'o', ms=12, alpha=0.4,
color='yellow', visible=False)
def onpress(self, event):
if self.lastind is None:
return
if event.key not in ('n', 'p'):
return
if event.key == 'n':
inc = 1
else:
inc = -1
self.lastind += inc
self.lastind = np.clip(self.lastind, 0, len(xs) - 1)
self.update()
def onpick(self, event):
if event.artist != line:
return True
N = len(event.ind)
if not N:
return True
# the click locations
x = event.mouseevent.xdata
y = event.mouseevent.ydata
distances = np.hypot(x - xs[event.ind], y - ys[event.ind])
indmin = distances.argmin()
dataind = event.ind[indmin]
self.lastind = dataind
self.update()
def update(self):
if self.lastind is None:
return
dataind = self.lastind
ax2.cla()
ax2.plot(X[dataind])
ax2.text(0.05, 0.9, 'mu=%1.3f\nsigma=%1.3f' % (xs[dataind], ys[dataind]),
transform=ax2.transAxes, va='top')
ax2.set_ylim(-0.5, 1.5)
self.selected.set_visible(True)
self.selected.set_data(xs[dataind], ys[dataind])
self.text.set_text('selected: %d' % dataind)
fig.canvas.draw()
if __name__ == '__main__':
import matplotlib.pyplot as plt
# Fixing random state for reproducibility
np.random.seed(19680801)
X = np.random.rand(100, 200)
xs = np.mean(X, axis=1)
ys = np.std(X, axis=1)
fig, (ax, ax2) = plt.subplots(2, 1)
ax.set_title('click on point to plot time series')
line, = ax.plot(xs, ys, 'o', picker=5) # 5 points tolerance
browser = PointBrowser()
fig.canvas.mpl_connect('pick_event', browser.onpick)
fig.canvas.mpl_connect('key_press_event', browser.onpress)
plt.show()
```
## 下载这个示例
- [下载python源码: data_browser.py](https://matplotlib.org/_downloads/data_browser.py)
- [下载Jupyter notebook: data_browser.ipynb](https://matplotlib.org/_downloads/data_browser.ipynb)

View File

@@ -0,0 +1,62 @@
# 图轴的进入和离开
通过更改进入和离开时的框架颜色来说明图形和轴进入和离开事件
```python
import matplotlib.pyplot as plt
def enter_axes(event):
print('enter_axes', event.inaxes)
event.inaxes.patch.set_facecolor('yellow')
event.canvas.draw()
def leave_axes(event):
print('leave_axes', event.inaxes)
event.inaxes.patch.set_facecolor('white')
event.canvas.draw()
def enter_figure(event):
print('enter_figure', event.canvas.figure)
event.canvas.figure.patch.set_facecolor('red')
event.canvas.draw()
def leave_figure(event):
print('leave_figure', event.canvas.figure)
event.canvas.figure.patch.set_facecolor('grey')
event.canvas.draw()
```
```python
fig1, (ax, ax2) = plt.subplots(2, 1)
fig1.suptitle('mouse hover over figure or axes to trigger events')
fig1.canvas.mpl_connect('figure_enter_event', enter_figure)
fig1.canvas.mpl_connect('figure_leave_event', leave_figure)
fig1.canvas.mpl_connect('axes_enter_event', enter_axes)
fig1.canvas.mpl_connect('axes_leave_event', leave_axes)
```
![图轴的进入和离开示例](https://matplotlib.org/_images/sphx_glr_figure_axes_enter_leave_001.png)
```python
fig2, (ax, ax2) = plt.subplots(2, 1)
fig2.suptitle('mouse hover over figure or axes to trigger events')
fig2.canvas.mpl_connect('figure_enter_event', enter_figure)
fig2.canvas.mpl_connect('figure_leave_event', leave_figure)
fig2.canvas.mpl_connect('axes_enter_event', enter_axes)
fig2.canvas.mpl_connect('axes_leave_event', leave_axes)
plt.show()
```
![图轴的进入和离开示例2](https://matplotlib.org/_images/sphx_glr_figure_axes_enter_leave_002.png)
## 下载这个示例
- [下载python源码: figure_axes_enter_leave.py](https://matplotlib.org/_downloads/figure_axes_enter_leave.py)
- [下载Jupyter notebook: figure_axes_enter_leave.ipynb](https://matplotlib.org/_downloads/figure_axes_enter_leave.ipynb)

View File

@@ -0,0 +1,19 @@
# Ginput 演示
这提供了交互功能的使用示例例如ginput。
```python
import matplotlib.pyplot as plt
import numpy as np
t = np.arange(10)
plt.plot(t, np.sin(t))
print("Please click")
x = plt.ginput(3)
print("clicked", x)
plt.show()
```
## 下载这个示例
- [下载python源码: ginput_demo_sgskip.py](https://matplotlib.org/_downloads/ginput_demo_sgskip.py)
- [下载Jupyter notebook: ginput_demo_sgskip.ipynb](https://matplotlib.org/_downloads/ginput_demo_sgskip.ipynb)

View File

@@ -0,0 +1,97 @@
# 交互功能
这提供了交互功能的使用示例例如ginputwaitforbuttonpress和手动clabel放置。
必须使用具有图形用户界面的后端以交互方式运行此脚本例如使用GTK3Agg后端而不是PS后端
另见: ginput_demo.py
```python
import time
import numpy as np
import matplotlib.pyplot as plt
def tellme(s):
print(s)
plt.title(s, fontsize=16)
plt.draw()
```
单击三个点定义三角形
```python
plt.clf()
plt.axis([-1., 1., -1., 1.])
plt.setp(plt.gca(), autoscale_on=False)
tellme('You will define a triangle, click to begin')
plt.waitforbuttonpress()
while True:
pts = []
while len(pts) < 3:
tellme('Select 3 corners with mouse')
pts = np.asarray(plt.ginput(3, timeout=-1))
if len(pts) < 3:
tellme('Too few points, starting over')
time.sleep(1) # Wait a second
ph = plt.fill(pts[:, 0], pts[:, 1], 'r', lw=2)
tellme('Happy? Key click for yes, mouse click for no')
if plt.waitforbuttonpress():
break
# Get rid of fill
for p in ph:
p.remove()
```
现在轮廓根据三角形角的距离 - 只是一个例子
```python
# Define a nice function of distance from individual pts
def f(x, y, pts):
z = np.zeros_like(x)
for p in pts:
z = z + 1/(np.sqrt((x - p[0])**2 + (y - p[1])**2))
return 1/z
X, Y = np.meshgrid(np.linspace(-1, 1, 51), np.linspace(-1, 1, 51))
Z = f(X, Y, pts)
CS = plt.contour(X, Y, Z, 20)
tellme('Use mouse to select contour label locations, middle button to finish')
CL = plt.clabel(CS, manual=True)
```
现在做一个缩放
```python
tellme('Now do a nested zoom, click to begin')
plt.waitforbuttonpress()
while True:
tellme('Select two corners of zoom, middle mouse button to finish')
pts = np.asarray(plt.ginput(2, timeout=-1))
if len(pts) < 2:
break
pts = np.sort(pts, axis=0)
plt.axis(pts.T.ravel())
tellme('All Done!')
plt.show()
```
## 下载这个示例
- [下载python源码: ginput_manual_clabel_sgskip.py](https://matplotlib.org/_downloads/ginput_manual_clabel_sgskip.py)
- [下载Jupyter notebook: ginput_manual_clabel_sgskip.ipynb](https://matplotlib.org/_downloads/ginput_manual_clabel_sgskip.ipynb)

View File

@@ -0,0 +1,52 @@
# 图像切片查看器
滚动三维阵列的二维图像切片。
![图像切片查看器](https://matplotlib.org/_images/sphx_glr_image_slices_viewer_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
class IndexTracker(object):
def __init__(self, ax, X):
self.ax = ax
ax.set_title('use scroll wheel to navigate images')
self.X = X
rows, cols, self.slices = X.shape
self.ind = self.slices//2
self.im = ax.imshow(self.X[:, :, self.ind])
self.update()
def onscroll(self, event):
print("%s %s" % (event.button, event.step))
if event.button == 'up':
self.ind = (self.ind + 1) % self.slices
else:
self.ind = (self.ind - 1) % self.slices
self.update()
def update(self):
self.im.set_data(self.X[:, :, self.ind])
ax.set_ylabel('slice %s' % self.ind)
self.im.axes.figure.canvas.draw()
fig, ax = plt.subplots(1, 1)
X = np.random.rand(20, 20, 40)
tracker = IndexTracker(ax, X)
fig.canvas.mpl_connect('scroll_event', tracker.onscroll)
plt.show()
```
## 下载这个示例
- [下载python源码: image_slices_viewer.py](https://matplotlib.org/_downloads/image_slices_viewer.py)
- [下载Jupyter notebook: image_slices_viewer.ipynb](https://matplotlib.org/_downloads/image_slices_viewer.ipynb)

View File

@@ -0,0 +1,3 @@
# 事件处理
Matplotlib支持使用GUI中立事件模型进行[事件处理](https://matplotlib.org/users/event_handling.html)因此您可以连接到Matplotlib事件而无需了解Matplotlib最终将插入哪个用户界面。 这有两个好处你编写的代码将更加可移植Matplotlib事件就像数据坐标空间和事件发生在哪些轴之类的东西所以你不必混淆低级转换细节来自画布空间到数据空间。还包括对象拾取示例。

View File

@@ -0,0 +1,38 @@
# 按键演示
显示如何连接到按键事件
![按键演示](https://matplotlib.org/_images/sphx_glr_keypress_demo_001.png)
```python
import sys
import numpy as np
import matplotlib.pyplot as plt
def press(event):
print('press', event.key)
sys.stdout.flush()
if event.key == 'x':
visible = xl.get_visible()
xl.set_visible(not visible)
fig.canvas.draw()
# Fixing random state for reproducibility
np.random.seed(19680801)
fig, ax = plt.subplots()
fig.canvas.mpl_connect('key_press_event', press)
ax.plot(np.random.rand(12), np.random.rand(12), 'go')
xl = ax.set_xlabel('easy come, easy go')
ax.set_title('Press a key')
plt.show()
```
## 下载这个示例
- [下载python源码: keypress_demo.py](https://matplotlib.org/_downloads/keypress_demo.py)
- [下载Jupyter notebook: keypress_demo.ipynb](https://matplotlib.org/_downloads/keypress_demo.ipynb)

View File

@@ -0,0 +1,92 @@
# 套索演示
演示如何使用套索选择一组点并获取所选点的索引。回调用于更改所选点的颜色。
这是一个概念验证实现尽管它可以按原样使用。将对API进行一些改进。
![套索演示](https://matplotlib.org/_images/sphx_glr_lasso_demo_001.png)
```python
from matplotlib import colors as mcolors, path
from matplotlib.collections import RegularPolyCollection
import matplotlib.pyplot as plt
from matplotlib.widgets import Lasso
import numpy as np
class Datum(object):
colorin = mcolors.to_rgba("red")
colorout = mcolors.to_rgba("blue")
def __init__(self, x, y, include=False):
self.x = x
self.y = y
if include:
self.color = self.colorin
else:
self.color = self.colorout
class LassoManager(object):
def __init__(self, ax, data):
self.axes = ax
self.canvas = ax.figure.canvas
self.data = data
self.Nxy = len(data)
facecolors = [d.color for d in data]
self.xys = [(d.x, d.y) for d in data]
self.collection = RegularPolyCollection(
6, sizes=(100,),
facecolors=facecolors,
offsets=self.xys,
transOffset=ax.transData)
ax.add_collection(self.collection)
self.cid = self.canvas.mpl_connect('button_press_event', self.onpress)
def callback(self, verts):
facecolors = self.collection.get_facecolors()
p = path.Path(verts)
ind = p.contains_points(self.xys)
for i in range(len(self.xys)):
if ind[i]:
facecolors[i] = Datum.colorin
else:
facecolors[i] = Datum.colorout
self.canvas.draw_idle()
self.canvas.widgetlock.release(self.lasso)
del self.lasso
def onpress(self, event):
if self.canvas.widgetlock.locked():
return
if event.inaxes is None:
return
self.lasso = Lasso(event.inaxes,
(event.xdata, event.ydata),
self.callback)
# acquire a lock on the widget drawing
self.canvas.widgetlock(self.lasso)
if __name__ == '__main__':
np.random.seed(19680801)
data = [Datum(*xy) for xy in np.random.rand(100, 2)]
ax = plt.axes(xlim=(0, 1), ylim=(0, 1), autoscale_on=False)
ax.set_title('Lasso points using left mouse button')
lman = LassoManager(ax, data)
plt.show()
```
## 下载这个示例
- [下载python源码: lasso_demo.py](https://matplotlib.org/_downloads/lasso_demo.py)
- [下载Jupyter notebook: lasso_demo.ipynb](https://matplotlib.org/_downloads/lasso_demo.ipynb)

View File

@@ -0,0 +1,55 @@
# 图例选择
启用图例上的拾取以打开和关闭原始线。
![图例选择](https://matplotlib.org/_images/sphx_glr_legend_picking_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
t = np.arange(0.0, 0.2, 0.1)
y1 = 2*np.sin(2*np.pi*t)
y2 = 4*np.sin(2*np.pi*2*t)
fig, ax = plt.subplots()
ax.set_title('Click on legend line to toggle line on/off')
line1, = ax.plot(t, y1, lw=2, color='red', label='1 HZ')
line2, = ax.plot(t, y2, lw=2, color='blue', label='2 HZ')
leg = ax.legend(loc='upper left', fancybox=True, shadow=True)
leg.get_frame().set_alpha(0.4)
# we will set up a dict mapping legend line to orig line, and enable
# picking on the legend line
lines = [line1, line2]
lined = dict()
for legline, origline in zip(leg.get_lines(), lines):
legline.set_picker(5) # 5 pts tolerance
lined[legline] = origline
def onpick(event):
# on the pick event, find the orig line corresponding to the
# legend proxy line, and toggle the visibility
legline = event.artist
origline = lined[legline]
vis = not origline.get_visible()
origline.set_visible(vis)
# Change the alpha on the line in the legend so we can see what lines
# have been toggled
if vis:
legline.set_alpha(1.0)
else:
legline.set_alpha(0.2)
fig.canvas.draw()
fig.canvas.mpl_connect('pick_event', onpick)
plt.show()
```
## 下载这个示例
- [下载python源码: legend_picking.py](https://matplotlib.org/_downloads/legend_picking.py)
- [下载Jupyter notebook: legend_picking.ipynb](https://matplotlib.org/_downloads/legend_picking.ipynb)

View File

@@ -0,0 +1,65 @@
# 镜子
例如,使用鼠标事件模拟用于检查数据的镜子。
![镜子示例](https://matplotlib.org/_images/sphx_glr_looking_glass_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
# Fixing random state for reproducibility
np.random.seed(19680801)
x, y = np.random.rand(2, 200)
fig, ax = plt.subplots()
circ = patches.Circle((0.5, 0.5), 0.25, alpha=0.8, fc='yellow')
ax.add_patch(circ)
ax.plot(x, y, alpha=0.2)
line, = ax.plot(x, y, alpha=1.0, clip_path=circ)
ax.set_title("Left click and drag to move looking glass")
class EventHandler(object):
def __init__(self):
fig.canvas.mpl_connect('button_press_event', self.onpress)
fig.canvas.mpl_connect('button_release_event', self.onrelease)
fig.canvas.mpl_connect('motion_notify_event', self.onmove)
self.x0, self.y0 = circ.center
self.pressevent = None
def onpress(self, event):
if event.inaxes != ax:
return
if not circ.contains(event)[0]:
return
self.pressevent = event
def onrelease(self, event):
self.pressevent = None
self.x0, self.y0 = circ.center
def onmove(self, event):
if self.pressevent is None or event.inaxes != self.pressevent.inaxes:
return
dx = event.xdata - self.pressevent.xdata
dy = event.ydata - self.pressevent.ydata
circ.center = self.x0 + dx, self.y0 + dy
line.set_clip_path(circ)
fig.canvas.draw()
handler = EventHandler()
plt.show()
```
## 下载这个示例
- [下载python源码: looking_glass.py](https://matplotlib.org/_downloads/looking_glass.py)
- [下载Jupyter notebook: looking_glass.ipynb](https://matplotlib.org/_downloads/looking_glass.ipynb)

View File

@@ -0,0 +1,164 @@
# 路径编辑器
跨GUI共享事件。
此示例演示了使用Matplotlib事件处理与画布上的对象进行交互和修改对象的跨GUI应用程序。
![路径编辑器示例](https://matplotlib.org/_images/sphx_glr_path_editor_001.png)
```python
import numpy as np
import matplotlib.path as mpath
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
Path = mpath.Path
fig, ax = plt.subplots()
pathdata = [
(Path.MOVETO, (1.58, -2.57)),
(Path.CURVE4, (0.35, -1.1)),
(Path.CURVE4, (-1.75, 2.0)),
(Path.CURVE4, (0.375, 2.0)),
(Path.LINETO, (0.85, 1.15)),
(Path.CURVE4, (2.2, 3.2)),
(Path.CURVE4, (3, 0.05)),
(Path.CURVE4, (2.0, -0.5)),
(Path.CLOSEPOLY, (1.58, -2.57)),
]
codes, verts = zip(*pathdata)
path = mpath.Path(verts, codes)
patch = mpatches.PathPatch(path, facecolor='green', edgecolor='yellow', alpha=0.5)
ax.add_patch(patch)
class PathInteractor(object):
"""
An path editor.
Key-bindings
't' toggle vertex markers on and off. When vertex markers are on,
you can move them, delete them
"""
showverts = True
epsilon = 5 # max pixel distance to count as a vertex hit
def __init__(self, pathpatch):
self.ax = pathpatch.axes
canvas = self.ax.figure.canvas
self.pathpatch = pathpatch
self.pathpatch.set_animated(True)
x, y = zip(*self.pathpatch.get_path().vertices)
self.line, = ax.plot(x, y, marker='o', markerfacecolor='r', animated=True)
self._ind = None # the active vert
canvas.mpl_connect('draw_event', self.draw_callback)
canvas.mpl_connect('button_press_event', self.button_press_callback)
canvas.mpl_connect('key_press_event', self.key_press_callback)
canvas.mpl_connect('button_release_event', self.button_release_callback)
canvas.mpl_connect('motion_notify_event', self.motion_notify_callback)
self.canvas = canvas
def draw_callback(self, event):
self.background = self.canvas.copy_from_bbox(self.ax.bbox)
self.ax.draw_artist(self.pathpatch)
self.ax.draw_artist(self.line)
self.canvas.blit(self.ax.bbox)
def pathpatch_changed(self, pathpatch):
'this method is called whenever the pathpatchgon object is called'
# only copy the artist props to the line (except visibility)
vis = self.line.get_visible()
plt.Artist.update_from(self.line, pathpatch)
self.line.set_visible(vis) # don't use the pathpatch visibility state
def get_ind_under_point(self, event):
'get the index of the vertex under point if within epsilon tolerance'
# display coords
xy = np.asarray(self.pathpatch.get_path().vertices)
xyt = self.pathpatch.get_transform().transform(xy)
xt, yt = xyt[:, 0], xyt[:, 1]
d = np.sqrt((xt - event.x)**2 + (yt - event.y)**2)
ind = d.argmin()
if d[ind] >= self.epsilon:
ind = None
return ind
def button_press_callback(self, event):
'whenever a mouse button is pressed'
if not self.showverts:
return
if event.inaxes is None:
return
if event.button != 1:
return
self._ind = self.get_ind_under_point(event)
def button_release_callback(self, event):
'whenever a mouse button is released'
if not self.showverts:
return
if event.button != 1:
return
self._ind = None
def key_press_callback(self, event):
'whenever a key is pressed'
if not event.inaxes:
return
if event.key == 't':
self.showverts = not self.showverts
self.line.set_visible(self.showverts)
if not self.showverts:
self._ind = None
self.canvas.draw()
def motion_notify_callback(self, event):
'on mouse movement'
if not self.showverts:
return
if self._ind is None:
return
if event.inaxes is None:
return
if event.button != 1:
return
x, y = event.xdata, event.ydata
vertices = self.pathpatch.get_path().vertices
vertices[self._ind] = x, y
self.line.set_data(zip(*vertices))
self.canvas.restore_region(self.background)
self.ax.draw_artist(self.pathpatch)
self.ax.draw_artist(self.line)
self.canvas.blit(self.ax.bbox)
interactor = PathInteractor(patch)
ax.set_title('drag vertices to update path')
ax.set_xlim(-3, 4)
ax.set_ylim(-3, 4)
plt.show()
```
## 下载这个示例
- [下载python源码: path_editor.py](https://matplotlib.org/_downloads/path_editor.py)
- [下载Jupyter notebook: path_editor.ipynb](https://matplotlib.org/_downloads/path_editor.ipynb)

View File

@@ -0,0 +1,154 @@
# 选择事件演示
您可以通过设置艺术家的“选择器”属性来启用拾取例如matplotlib Line2DTextPatchPolygonAxesImage等...
选择器属性有多种含义
- None - 此艺术家对象的选择功能已停用(默认)
- boolean - 如果为True则启用拾取如果鼠标事件在艺术家上方艺术家将触发拾取事件
- float - 如果选择器是一个数字则它被解释为以点为单位的epsilon容差如果事件的数据在鼠标事件的epsilon内则艺术家将触发事件。 对于某些艺术家如线条和补丁集合艺术家可能会为生成的挑选事件提供其他数据例如挑选事件的epsilon中的数据索引
- function - 如果选择器是可调用的,则它是用户提供的函数,用于确定艺术家是否被鼠标事件命中。
hit, props = picker(artist, mouseevent)
确定命中测试。 如果鼠标事件在艺术家上方则返回hit = Trueprops是要添加到PickEvent属性的属性字典
通过设置“选取器”属性启用艺术家进行拾取后您需要连接到图形画布pick_event以获取鼠标按下事件的拾取回调。 例如,
def pick_handler(event):
mouseevent = event.mouseevent artist = event.artist # now do something with this...
传递给回调的pick事件matplotlib.backend_bases.PickEvent始终使用两个属性触发
- mouseevent - 生成拾取事件的鼠标事件。 鼠标事件又具有x和y显示空间中的坐标如左下角的像素和xdataydata数据空间中的坐标等属性。 此外您可以获取有关按下哪些按钮按下哪些键鼠标所在的轴等的信息。有关详细信息请参阅matplotlib.backend_bases.MouseEvent。
- artist - 生成pick事件的matplotlib.artist。
此外某些艺术家如Line2D和PatchCollection可能会将其他元数据如索引附加到符合选择器条件的数据中例如行中指定的epsilon容差范围内的所有点
以下示例说明了这些方法中的每一种。
![选择事件示例](https://matplotlib.org/_images/sphx_glr_pick_event_demo_001.png)
![选择事件示例2](https://matplotlib.org/_images/sphx_glr_pick_event_demo_002.png)
![选择事件示例3](https://matplotlib.org/_images/sphx_glr_pick_event_demo_003.png)
![选择事件示例4](https://matplotlib.org/_images/sphx_glr_pick_event_demo_004.png)
```python
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
from matplotlib.patches import Rectangle
from matplotlib.text import Text
from matplotlib.image import AxesImage
import numpy as np
from numpy.random import rand
if 1: # simple picking, lines, rectangles and text
fig, (ax1, ax2) = plt.subplots(2, 1)
ax1.set_title('click on points, rectangles or text', picker=True)
ax1.set_ylabel('ylabel', picker=True, bbox=dict(facecolor='red'))
line, = ax1.plot(rand(100), 'o', picker=5) # 5 points tolerance
# pick the rectangle
bars = ax2.bar(range(10), rand(10), picker=True)
for label in ax2.get_xticklabels(): # make the xtick labels pickable
label.set_picker(True)
def onpick1(event):
if isinstance(event.artist, Line2D):
thisline = event.artist
xdata = thisline.get_xdata()
ydata = thisline.get_ydata()
ind = event.ind
print('onpick1 line:', zip(np.take(xdata, ind), np.take(ydata, ind)))
elif isinstance(event.artist, Rectangle):
patch = event.artist
print('onpick1 patch:', patch.get_path())
elif isinstance(event.artist, Text):
text = event.artist
print('onpick1 text:', text.get_text())
fig.canvas.mpl_connect('pick_event', onpick1)
if 1: # picking with a custom hit test function
# you can define custom pickers by setting picker to a callable
# function. The function has the signature
#
# hit, props = func(artist, mouseevent)
#
# to determine the hit test. if the mouse event is over the artist,
# return hit=True and props is a dictionary of
# properties you want added to the PickEvent attributes
def line_picker(line, mouseevent):
"""
find the points within a certain distance from the mouseclick in
data coords and attach some extra attributes, pickx and picky
which are the data points that were picked
"""
if mouseevent.xdata is None:
return False, dict()
xdata = line.get_xdata()
ydata = line.get_ydata()
maxd = 0.05
d = np.sqrt((xdata - mouseevent.xdata)**2. + (ydata - mouseevent.ydata)**2.)
ind = np.nonzero(np.less_equal(d, maxd))
if len(ind):
pickx = np.take(xdata, ind)
picky = np.take(ydata, ind)
props = dict(ind=ind, pickx=pickx, picky=picky)
return True, props
else:
return False, dict()
def onpick2(event):
print('onpick2 line:', event.pickx, event.picky)
fig, ax = plt.subplots()
ax.set_title('custom picker for line data')
line, = ax.plot(rand(100), rand(100), 'o', picker=line_picker)
fig.canvas.mpl_connect('pick_event', onpick2)
if 1: # picking on a scatter plot (matplotlib.collections.RegularPolyCollection)
x, y, c, s = rand(4, 100)
def onpick3(event):
ind = event.ind
print('onpick3 scatter:', ind, np.take(x, ind), np.take(y, ind))
fig, ax = plt.subplots()
col = ax.scatter(x, y, 100*s, c, picker=True)
#fig.savefig('pscoll.eps')
fig.canvas.mpl_connect('pick_event', onpick3)
if 1: # picking images (matplotlib.image.AxesImage)
fig, ax = plt.subplots()
im1 = ax.imshow(rand(10, 5), extent=(1, 2, 1, 2), picker=True)
im2 = ax.imshow(rand(5, 10), extent=(3, 4, 1, 2), picker=True)
im3 = ax.imshow(rand(20, 25), extent=(1, 2, 3, 4), picker=True)
im4 = ax.imshow(rand(30, 12), extent=(3, 4, 3, 4), picker=True)
ax.axis([0, 5, 0, 5])
def onpick4(event):
artist = event.artist
if isinstance(artist, AxesImage):
im = artist
A = im.get_array()
print('onpick4 image', A.shape)
fig.canvas.mpl_connect('pick_event', onpick4)
plt.show()
```
## 下载这个示例
- [下载python源码: pick_event_demo.py](https://matplotlib.org/_downloads/pick_event_demo.py)
- [下载Jupyter notebook: pick_event_demo.ipynb](https://matplotlib.org/_downloads/pick_event_demo.ipynb)

View File

@@ -0,0 +1,47 @@
# 选择事件演示2
计算100个数据集的平均值和标准差stddev并绘制平均值vs stddev。单击其中一个musigma点时绘制生成均值和stddev的数据集中的原始数据。
![选择事件演示2](https://matplotlib.org/_images/sphx_glr_pick_event_demo2_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
X = np.random.rand(100, 1000)
xs = np.mean(X, axis=1)
ys = np.std(X, axis=1)
fig, ax = plt.subplots()
ax.set_title('click on point to plot time series')
line, = ax.plot(xs, ys, 'o', picker=5) # 5 points tolerance
def onpick(event):
if event.artist != line:
return True
N = len(event.ind)
if not N:
return True
figi, axs = plt.subplots(N, squeeze=False)
for ax, dataind in zip(axs.flat, event.ind):
ax.plot(X[dataind])
ax.text(.05, .9, 'mu=%1.3f\nsigma=%1.3f' % (xs[dataind], ys[dataind]),
transform=ax.transAxes, va='top')
ax.set_ylim(-0.5, 1.5)
figi.show()
return True
fig.canvas.mpl_connect('pick_event', onpick)
plt.show()
```
## 下载这个示例
- [下载python源码: pick_event_demo2.py](https://matplotlib.org/_downloads/pick_event_demo2.py)
- [下载Jupyter notebook: pick_event_demo2.ipynb](https://matplotlib.org/_downloads/pick_event_demo2.ipynb)

View File

@@ -0,0 +1,291 @@
# Pipong
一个基于Matplotlib的Pong游戏说明了一种编写交互动画的方法它很容易移植到多个后端pipong.py由Paul Ivanov撰写<http://pirsquared.org>
```python
import numpy as np
import matplotlib.pyplot as plt
from numpy.random import randn, randint
from matplotlib.font_manager import FontProperties
instructions = """
Player A: Player B:
'e' up 'i'
'd' down 'k'
press 't' -- close these instructions
(animation will be much faster)
press 'a' -- add a puck
press 'A' -- remove a puck
press '1' -- slow down all pucks
press '2' -- speed up all pucks
press '3' -- slow down distractors
press '4' -- speed up distractors
press ' ' -- reset the first puck
press 'n' -- toggle distractors on/off
press 'g' -- toggle the game on/off
"""
class Pad(object):
def __init__(self, disp, x, y, type='l'):
self.disp = disp
self.x = x
self.y = y
self.w = .3
self.score = 0
self.xoffset = 0.3
self.yoffset = 0.1
if type == 'r':
self.xoffset *= -1.0
if type == 'l' or type == 'r':
self.signx = -1.0
self.signy = 1.0
else:
self.signx = 1.0
self.signy = -1.0
def contains(self, loc):
return self.disp.get_bbox().contains(loc.x, loc.y)
class Puck(object):
def __init__(self, disp, pad, field):
self.vmax = .2
self.disp = disp
self.field = field
self._reset(pad)
def _reset(self, pad):
self.x = pad.x + pad.xoffset
if pad.y < 0:
self.y = pad.y + pad.yoffset
else:
self.y = pad.y - pad.yoffset
self.vx = pad.x - self.x
self.vy = pad.y + pad.w/2 - self.y
self._speedlimit()
self._slower()
self._slower()
def update(self, pads):
self.x += self.vx
self.y += self.vy
for pad in pads:
if pad.contains(self):
self.vx *= 1.2 * pad.signx
self.vy *= 1.2 * pad.signy
fudge = .001
# probably cleaner with something like...
if self.x < fudge:
pads[1].score += 1
self._reset(pads[0])
return True
if self.x > 7 - fudge:
pads[0].score += 1
self._reset(pads[1])
return True
if self.y < -1 + fudge or self.y > 1 - fudge:
self.vy *= -1.0
# add some randomness, just to make it interesting
self.vy -= (randn()/300.0 + 1/300.0) * np.sign(self.vy)
self._speedlimit()
return False
def _slower(self):
self.vx /= 5.0
self.vy /= 5.0
def _faster(self):
self.vx *= 5.0
self.vy *= 5.0
def _speedlimit(self):
if self.vx > self.vmax:
self.vx = self.vmax
if self.vx < -self.vmax:
self.vx = -self.vmax
if self.vy > self.vmax:
self.vy = self.vmax
if self.vy < -self.vmax:
self.vy = -self.vmax
class Game(object):
def __init__(self, ax):
# create the initial line
self.ax = ax
ax.set_ylim([-1, 1])
ax.set_xlim([0, 7])
padAx = 0
padBx = .50
padAy = padBy = .30
padBx += 6.3
# pads
pA, = self.ax.barh(padAy, .2,
height=.3, color='k', alpha=.5, edgecolor='b',
lw=2, label="Player B",
animated=True)
pB, = self.ax.barh(padBy, .2,
height=.3, left=padBx, color='k', alpha=.5,
edgecolor='r', lw=2, label="Player A",
animated=True)
# distractors
self.x = np.arange(0, 2.22*np.pi, 0.01)
self.line, = self.ax.plot(self.x, np.sin(self.x), "r",
animated=True, lw=4)
self.line2, = self.ax.plot(self.x, np.cos(self.x), "g",
animated=True, lw=4)
self.line3, = self.ax.plot(self.x, np.cos(self.x), "g",
animated=True, lw=4)
self.line4, = self.ax.plot(self.x, np.cos(self.x), "r",
animated=True, lw=4)
# center line
self.centerline, = self.ax.plot([3.5, 3.5], [1, -1], 'k',
alpha=.5, animated=True, lw=8)
# puck (s)
self.puckdisp = self.ax.scatter([1], [1], label='_nolegend_',
s=200, c='g',
alpha=.9, animated=True)
self.canvas = self.ax.figure.canvas
self.background = None
self.cnt = 0
self.distract = True
self.res = 100.0
self.on = False
self.inst = True # show instructions from the beginning
self.background = None
self.pads = []
self.pads.append(Pad(pA, padAx, padAy))
self.pads.append(Pad(pB, padBx, padBy, 'r'))
self.pucks = []
self.i = self.ax.annotate(instructions, (.5, 0.5),
name='monospace',
verticalalignment='center',
horizontalalignment='center',
multialignment='left',
textcoords='axes fraction',
animated=False)
self.canvas.mpl_connect('key_press_event', self.key_press)
def draw(self, evt):
draw_artist = self.ax.draw_artist
if self.background is None:
self.background = self.canvas.copy_from_bbox(self.ax.bbox)
# restore the clean slate background
self.canvas.restore_region(self.background)
# show the distractors
if self.distract:
self.line.set_ydata(np.sin(self.x + self.cnt/self.res))
self.line2.set_ydata(np.cos(self.x - self.cnt/self.res))
self.line3.set_ydata(np.tan(self.x + self.cnt/self.res))
self.line4.set_ydata(np.tan(self.x - self.cnt/self.res))
draw_artist(self.line)
draw_artist(self.line2)
draw_artist(self.line3)
draw_artist(self.line4)
# pucks and pads
if self.on:
self.ax.draw_artist(self.centerline)
for pad in self.pads:
pad.disp.set_y(pad.y)
pad.disp.set_x(pad.x)
self.ax.draw_artist(pad.disp)
for puck in self.pucks:
if puck.update(self.pads):
# we only get here if someone scored
self.pads[0].disp.set_label(
" " + str(self.pads[0].score))
self.pads[1].disp.set_label(
" " + str(self.pads[1].score))
self.ax.legend(loc='center', framealpha=.2,
facecolor='0.5',
prop=FontProperties(size='xx-large',
weight='bold'))
self.background = None
self.ax.figure.canvas.draw_idle()
return True
puck.disp.set_offsets([[puck.x, puck.y]])
self.ax.draw_artist(puck.disp)
# just redraw the axes rectangle
self.canvas.blit(self.ax.bbox)
self.canvas.flush_events()
if self.cnt == 50000:
# just so we don't get carried away
print("...and you've been playing for too long!!!")
plt.close()
self.cnt += 1
return True
def key_press(self, event):
if event.key == '3':
self.res *= 5.0
if event.key == '4':
self.res /= 5.0
if event.key == 'e':
self.pads[0].y += .1
if self.pads[0].y > 1 - .3:
self.pads[0].y = 1 - .3
if event.key == 'd':
self.pads[0].y -= .1
if self.pads[0].y < -1:
self.pads[0].y = -1
if event.key == 'i':
self.pads[1].y += .1
if self.pads[1].y > 1 - .3:
self.pads[1].y = 1 - .3
if event.key == 'k':
self.pads[1].y -= .1
if self.pads[1].y < -1:
self.pads[1].y = -1
if event.key == 'a':
self.pucks.append(Puck(self.puckdisp,
self.pads[randint(2)],
self.ax.bbox))
if event.key == 'A' and len(self.pucks):
self.pucks.pop()
if event.key == ' ' and len(self.pucks):
self.pucks[0]._reset(self.pads[randint(2)])
if event.key == '1':
for p in self.pucks:
p._slower()
if event.key == '2':
for p in self.pucks:
p._faster()
if event.key == 'n':
self.distract = not self.distract
if event.key == 'g':
self.on = not self.on
if event.key == 't':
self.inst = not self.inst
self.i.set_visible(not self.i.get_visible())
self.background = None
self.canvas.draw_idle()
if event.key == 'q':
plt.close()
```
## 下载这个示例
- [下载python源码: pipong.py](https://matplotlib.org/_downloads/pipong.py)
- [下载Jupyter notebook: pipong.ipynb](https://matplotlib.org/_downloads/pipong.ipynb)

View File

@@ -0,0 +1,187 @@
# 综合编辑器
这是一个示例展示如何使用Matplotlib事件处理来构建跨GUI应用程序以与画布上的对象进行交互。
![综合编辑器示例](https://matplotlib.org/_images/sphx_glr_poly_editor_001.png)
```python
import numpy as np
from matplotlib.lines import Line2D
from matplotlib.artist import Artist
from matplotlib.mlab import dist_point_to_segment
class PolygonInteractor(object):
"""
A polygon editor.
Key-bindings
't' toggle vertex markers on and off. When vertex markers are on,
you can move them, delete them
'd' delete the vertex under point
'i' insert a vertex at point. You must be within epsilon of the
line connecting two existing vertices
"""
showverts = True
epsilon = 5 # max pixel distance to count as a vertex hit
def __init__(self, ax, poly):
if poly.figure is None:
raise RuntimeError('You must first add the polygon to a figure '
'or canvas before defining the interactor')
self.ax = ax
canvas = poly.figure.canvas
self.poly = poly
x, y = zip(*self.poly.xy)
self.line = Line2D(x, y,
marker='o', markerfacecolor='r',
animated=True)
self.ax.add_line(self.line)
self.cid = self.poly.add_callback(self.poly_changed)
self._ind = None # the active vert
canvas.mpl_connect('draw_event', self.draw_callback)
canvas.mpl_connect('button_press_event', self.button_press_callback)
canvas.mpl_connect('key_press_event', self.key_press_callback)
canvas.mpl_connect('button_release_event', self.button_release_callback)
canvas.mpl_connect('motion_notify_event', self.motion_notify_callback)
self.canvas = canvas
def draw_callback(self, event):
self.background = self.canvas.copy_from_bbox(self.ax.bbox)
self.ax.draw_artist(self.poly)
self.ax.draw_artist(self.line)
# do not need to blit here, this will fire before the screen is
# updated
def poly_changed(self, poly):
'this method is called whenever the polygon object is called'
# only copy the artist props to the line (except visibility)
vis = self.line.get_visible()
Artist.update_from(self.line, poly)
self.line.set_visible(vis) # don't use the poly visibility state
def get_ind_under_point(self, event):
'get the index of the vertex under point if within epsilon tolerance'
# display coords
xy = np.asarray(self.poly.xy)
xyt = self.poly.get_transform().transform(xy)
xt, yt = xyt[:, 0], xyt[:, 1]
d = np.hypot(xt - event.x, yt - event.y)
indseq, = np.nonzero(d == d.min())
ind = indseq[0]
if d[ind] >= self.epsilon:
ind = None
return ind
def button_press_callback(self, event):
'whenever a mouse button is pressed'
if not self.showverts:
return
if event.inaxes is None:
return
if event.button != 1:
return
self._ind = self.get_ind_under_point(event)
def button_release_callback(self, event):
'whenever a mouse button is released'
if not self.showverts:
return
if event.button != 1:
return
self._ind = None
def key_press_callback(self, event):
'whenever a key is pressed'
if not event.inaxes:
return
if event.key == 't':
self.showverts = not self.showverts
self.line.set_visible(self.showverts)
if not self.showverts:
self._ind = None
elif event.key == 'd':
ind = self.get_ind_under_point(event)
if ind is not None:
self.poly.xy = np.delete(self.poly.xy,
ind, axis=0)
self.line.set_data(zip(*self.poly.xy))
elif event.key == 'i':
xys = self.poly.get_transform().transform(self.poly.xy)
p = event.x, event.y # display coords
for i in range(len(xys) - 1):
s0 = xys[i]
s1 = xys[i + 1]
d = dist_point_to_segment(p, s0, s1)
if d <= self.epsilon:
self.poly.xy = np.insert(
self.poly.xy, i+1,
[event.xdata, event.ydata],
axis=0)
self.line.set_data(zip(*self.poly.xy))
break
if self.line.stale:
self.canvas.draw_idle()
def motion_notify_callback(self, event):
'on mouse movement'
if not self.showverts:
return
if self._ind is None:
return
if event.inaxes is None:
return
if event.button != 1:
return
x, y = event.xdata, event.ydata
self.poly.xy[self._ind] = x, y
if self._ind == 0:
self.poly.xy[-1] = x, y
elif self._ind == len(self.poly.xy) - 1:
self.poly.xy[0] = x, y
self.line.set_data(zip(*self.poly.xy))
self.canvas.restore_region(self.background)
self.ax.draw_artist(self.poly)
self.ax.draw_artist(self.line)
self.canvas.blit(self.ax.bbox)
if __name__ == '__main__':
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
theta = np.arange(0, 2*np.pi, 0.1)
r = 1.5
xs = r * np.cos(theta)
ys = r * np.sin(theta)
poly = Polygon(np.column_stack([xs, ys]), animated=True)
fig, ax = plt.subplots()
ax.add_patch(poly)
p = PolygonInteractor(ax, poly)
ax.set_title('Click and drag a point to move it')
ax.set_xlim((-2, 2))
ax.set_ylim((-2, 2))
plt.show()
```
## 下载这个示例
- [下载python源码: poly_editor.py](https://matplotlib.org/_downloads/poly_editor.py)
- [下载Jupyter notebook: poly_editor.ipynb](https://matplotlib.org/_downloads/poly_editor.ipynb)

View File

@@ -0,0 +1,54 @@
# Pong
一个使用Matplotlib的小游戏演示。
此示例需要[pipong.py](https://matplotlib.org/_downloads/9a2d2c527d869cd1b03d9560d75d6a71/pipong.py)
```python
import time
import matplotlib.pyplot as plt
import pipong
fig, ax = plt.subplots()
canvas = ax.figure.canvas
animation = pipong.Game(ax)
# disable the default key bindings
if fig.canvas.manager.key_press_handler_id is not None:
canvas.mpl_disconnect(fig.canvas.manager.key_press_handler_id)
# reset the blitting background on redraw
def handle_redraw(event):
animation.background = None
# bootstrap after the first draw
def start_anim(event):
canvas.mpl_disconnect(start_anim.cid)
def local_draw():
if animation.ax._cachedRenderer:
animation.draw(None)
start_anim.timer.add_callback(local_draw)
start_anim.timer.start()
canvas.mpl_connect('draw_event', handle_redraw)
start_anim.cid = canvas.mpl_connect('draw_event', start_anim)
start_anim.timer = animation.canvas.new_timer()
start_anim.timer.interval = 1
tstart = time.time()
plt.show()
print('FPS: %f' % (animation.cnt/(time.time() - tstart)))
```
## 下载这个示例
- [下载python源码: pong_sgskip.py](https://matplotlib.org/_downloads/pong_sgskip.py)
- [下载Jupyter notebook: pong_sgskip.ipynb](https://matplotlib.org/_downloads/pong_sgskip.ipynb)

View File

@@ -0,0 +1,73 @@
# 重采样数据
下采样会降低信号的采样率或采样大小。在本教程中,当通过拖动和缩放调整打印时,将对信号进行缩减采样。
![重采样数据示例](https://matplotlib.org/_images/sphx_glr_resample_001.png)
```python
import numpy as np
import matplotlib.pyplot as plt
# A class that will downsample the data and recompute when zoomed.
class DataDisplayDownsampler(object):
def __init__(self, xdata, ydata):
self.origYData = ydata
self.origXData = xdata
self.max_points = 50
self.delta = xdata[-1] - xdata[0]
def downsample(self, xstart, xend):
# get the points in the view range
mask = (self.origXData > xstart) & (self.origXData < xend)
# dilate the mask by one to catch the points just outside
# of the view range to not truncate the line
mask = np.convolve([1, 1], mask, mode='same').astype(bool)
# sort out how many points to drop
ratio = max(np.sum(mask) // self.max_points, 1)
# mask data
xdata = self.origXData[mask]
ydata = self.origYData[mask]
# downsample data
xdata = xdata[::ratio]
ydata = ydata[::ratio]
print("using {} of {} visible points".format(
len(ydata), np.sum(mask)))
return xdata, ydata
def update(self, ax):
# Update the line
lims = ax.viewLim
if np.abs(lims.width - self.delta) > 1e-8:
self.delta = lims.width
xstart, xend = lims.intervalx
self.line.set_data(*self.downsample(xstart, xend))
ax.figure.canvas.draw_idle()
# Create a signal
xdata = np.linspace(16, 365, (365-16)*4)
ydata = np.sin(2*np.pi*xdata/153) + np.cos(2*np.pi*xdata/127)
d = DataDisplayDownsampler(xdata, ydata)
fig, ax = plt.subplots()
# Hook up the line
d.line, = ax.plot(xdata, ydata, 'o-')
ax.set_autoscale_on(False) # Otherwise, infinite loop
# Connect for changing the view limits
ax.callbacks.connect('xlim_changed', d.update)
ax.set_xlim(16, 365)
plt.show()
```
## 下载这个示例
- [下载python源码: resample.py](https://matplotlib.org/_downloads/resample.py)
- [下载Jupyter notebook: resample.ipynb](https://matplotlib.org/_downloads/resample.ipynb)

View File

@@ -0,0 +1,40 @@
# 计时器
使用通用计时器对象的简单示例。这用于更新图中标题的时间。
![计时器示例](https://matplotlib.org/_images/sphx_glr_timers_001.png)
```python
import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime
def update_title(axes):
axes.set_title(datetime.now())
axes.figure.canvas.draw()
fig, ax = plt.subplots()
x = np.linspace(-3, 3)
ax.plot(x, x ** 2)
# Create a new timer object. Set the interval to 100 milliseconds
# (1000 is default) and tell the timer what function should be called.
timer = fig.canvas.new_timer(interval=100)
timer.add_callback(update_title, ax)
timer.start()
# Or could start the timer on first figure draw
#def start_timer(evt):
# timer.start()
# fig.canvas.mpl_disconnect(drawid)
#drawid = fig.canvas.mpl_connect('draw_event', start_timer)
plt.show()
```
## 下载这个示例
- [下载python源码: timers.py](https://matplotlib.org/_downloads/timers.py)
- [下载Jupyter notebook: timers.ipynb](https://matplotlib.org/_downloads/timers.ipynb)

Some files were not shown because too many files have changed in this diff Show More