mirror of
https://github.com/Estom/notes.git
synced 2026-02-03 10:33:35 +08:00
matplotlib & pandas
This commit is contained in:
335
Python/matplotlab/README.md
Normal file
335
Python/matplotlab/README.md
Normal 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>
|
||||
265
Python/matplotlab/advanced/path_tutorial.md
Normal file
265
Python/matplotlab/advanced/path_tutorial.md
Normal 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 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)
|
||||
|
||||
122
Python/matplotlab/advanced/patheffects_guide.md
Normal file
122
Python/matplotlab/advanced/patheffects_guide.md
Normal 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 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)
|
||||
|
||||
615
Python/matplotlab/advanced/transforms_tutorial.md
Normal file
615
Python/matplotlab/advanced/transforms_tutorial.md
Normal 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
::: 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
::: 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
::: 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
::: 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)
|
||||
|
||||
123
Python/matplotlab/colors/colorbar_only.md
Normal file
123
Python/matplotlab/colors/colorbar_only.md
Normal 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 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)
|
||||
|
||||
311
Python/matplotlab/colors/colormap-manipulation.md
Normal file
311
Python/matplotlab/colors/colormap-manipulation.md
Normal 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])
|
||||
```
|
||||
|
||||

|
||||
|
||||
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])
|
||||
```
|
||||
|
||||

|
||||
|
||||
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])
|
||||
```
|
||||
|
||||

|
||||
|
||||
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])
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 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)
|
||||
```
|
||||
|
||||

|
||||
|
||||
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)
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
|
||||
281
Python/matplotlab/colors/colormapnorms.md
Normal file
281
Python/matplotlab/colors/colormapnorms.md
Normal 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
**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)
|
||||
|
||||
521
Python/matplotlab/colors/colormaps.md
Normal file
521
Python/matplotlab/colors/colormaps.md
Normal 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()
|
||||
```
|
||||
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
|
||||
## 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()
|
||||
```
|
||||
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
|
||||
## 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)
|
||||
```
|
||||
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
- 
|
||||
|
||||
## 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)
|
||||
|
||||
135
Python/matplotlab/colors/colors.md
Normal file
135
Python/matplotlab/colors/colors.md
Normal 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')
|
||||
```
|
||||
|
||||
- 
|
||||
- 
|
||||
|
||||
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')
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 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)
|
||||
|
||||
3911
Python/matplotlab/gallery/README.md
Normal file
3911
Python/matplotlab/gallery/README.md
Normal file
File diff suppressed because it is too large
Load Diff
59
Python/matplotlab/gallery/animation/animate_decay.md
Normal file
59
Python/matplotlab/gallery/animation/animate_decay.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# 衰变
|
||||
|
||||
这个例子展示了:
|
||||
- 使用生成器来驱动动画,
|
||||
- 在动画期间更改轴限制。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
89
Python/matplotlab/gallery/animation/animated_histogram.md
Normal file
89
Python/matplotlab/gallery/animation/animated_histogram.md
Normal 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到顶点2,v2到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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载python源码: animated_histogram.py](https://matplotlib.org/_downloads/animated_histogram.py)
|
||||
- [下载Jupyter notebook: animated_histogram.ipynb](https://matplotlib.org/_downloads/animated_histogram.ipynb)
|
||||
33
Python/matplotlab/gallery/animation/animation_demo.md
Normal file
33
Python/matplotlab/gallery/animation/animation_demo.md
Normal 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)将不起作用。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
71
Python/matplotlab/gallery/animation/bayes_update.md
Normal file
71
Python/matplotlab/gallery/animation/bayes_update.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# 贝叶斯更新
|
||||
|
||||
此动画显示在新数据到达时重新安装的后验估计更新。
|
||||
|
||||
垂直线表示绘制的分布应该收敛的理论值。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -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)
|
||||
47
Python/matplotlab/gallery/animation/dynamic_image.md
Normal file
47
Python/matplotlab/gallery/animation/dynamic_image.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# 使用预先计算的图像列表的动画图像
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
39
Python/matplotlab/gallery/animation/frame_grabbing_sgskip.md
Normal file
39
Python/matplotlab/gallery/animation/frame_grabbing_sgskip.md
Normal 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)
|
||||
75
Python/matplotlab/gallery/animation/rain.md
Normal file
75
Python/matplotlab/gallery/animation/rain.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# 雨模拟
|
||||
|
||||
通过设置50个散点的比例和不透明度来模拟表面上的雨滴。
|
||||
|
||||
作者:Nicolas P. Rougier
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
75
Python/matplotlab/gallery/animation/random_walk.md
Normal file
75
Python/matplotlab/gallery/animation/random_walk.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# 动画3D随机游走
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
45
Python/matplotlab/gallery/animation/simple_anim.md
Normal file
45
Python/matplotlab/gallery/animation/simple_anim.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# 动画线图
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
67
Python/matplotlab/gallery/animation/strip_chart.md
Normal file
67
Python/matplotlab/gallery/animation/strip_chart.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# 示波器
|
||||
|
||||
模拟示波器。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
77
Python/matplotlab/gallery/animation/unchained.md
Normal file
77
Python/matplotlab/gallery/animation/unchained.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# MATPLOTLIB UNCHAINED
|
||||
|
||||
脉冲星的假信号频率的比较路径演示(主要是因为Joy Division的未知乐趣的封面而闻名)。
|
||||
|
||||
作者:Nicolas P. Rougier
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,83 @@
|
||||
# 演示锚定方向箭头
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
137
Python/matplotlab/gallery/axes_grid1/demo_axes_divider.md
Normal file
137
Python/matplotlab/gallery/axes_grid1/demo_axes_divider.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# 演示Axes Divider
|
||||
|
||||
轴分割器用于计算轴的位置,并使用现有轴实例为它们创建分隔线。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
144
Python/matplotlab/gallery/axes_grid1/demo_axes_grid.md
Normal file
144
Python/matplotlab/gallery/axes_grid1/demo_axes_grid.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# 演示Axes Grid
|
||||
|
||||
具有单个或自己的彩条的2x2图像的网格。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
125
Python/matplotlab/gallery/axes_grid1/demo_axes_grid2.md
Normal file
125
Python/matplotlab/gallery/axes_grid1/demo_axes_grid2.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# 演示Axes Grid2
|
||||
|
||||
共享xaxis和yaxis的图像网格。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,62 @@
|
||||
# 演示轴 Hbox Divider
|
||||
|
||||
HBox Divider用于排列子图。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
99
Python/matplotlab/gallery/axes_grid1/demo_axes_rgb.md
Normal file
99
Python/matplotlab/gallery/axes_grid1/demo_axes_rgb.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# 演示轴 RGB
|
||||
|
||||
RGBAxes显示RGB合成图像。
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,57 @@
|
||||
# 演示嵌入轴颜色条
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# 演示带轴分割器的颜色条
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,43 @@
|
||||
# 使用插入定位器演示Colorbar
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
98
Python/matplotlab/gallery/axes_grid1/demo_edge_colorbar.md
Normal file
98
Python/matplotlab/gallery/axes_grid1/demo_edge_colorbar.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# 演示Edge Colorbar
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
62
Python/matplotlab/gallery/axes_grid1/demo_fixed_size_axes.md
Normal file
62
Python/matplotlab/gallery/axes_grid1/demo_fixed_size_axes.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# 演示固定尺寸轴
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,31 @@
|
||||
# 演示Imagegrid Aspect
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
137
Python/matplotlab/gallery/axes_grid1/inset_locator_demo.md
Normal file
137
Python/matplotlab/gallery/axes_grid1/inset_locator_demo.md
Normal 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
参数``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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
在上述方法中,使用了轴变换和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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载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)
|
||||
89
Python/matplotlab/gallery/axes_grid1/inset_locator_demo2.md
Normal file
89
Python/matplotlab/gallery/axes_grid1/inset_locator_demo2.md
Normal 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) 创建与感兴趣区域的连接。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,76 @@
|
||||
# 使用Axesgrid为Ylabel腾出空间
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
```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)
|
||||
34
Python/matplotlab/gallery/axes_grid1/parasite_simple.md
Normal file
34
Python/matplotlab/gallery/axes_grid1/parasite_simple.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# 简单寄生示例
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
52
Python/matplotlab/gallery/axes_grid1/parasite_simple2.md
Normal file
52
Python/matplotlab/gallery/axes_grid1/parasite_simple2.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# 简单寄生示例2
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,59 @@
|
||||
# 散点图
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -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)中找到。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
38
Python/matplotlab/gallery/axes_grid1/simple_axes_divider1.md
Normal file
38
Python/matplotlab/gallery/axes_grid1/simple_axes_divider1.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# 简单轴分割器示例1
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
38
Python/matplotlab/gallery/axes_grid1/simple_axes_divider2.md
Normal file
38
Python/matplotlab/gallery/axes_grid1/simple_axes_divider2.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# 简单轴分割器示例2
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
47
Python/matplotlab/gallery/axes_grid1/simple_axes_divider3.md
Normal file
47
Python/matplotlab/gallery/axes_grid1/simple_axes_divider3.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# 简单轴分割器示例3
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
28
Python/matplotlab/gallery/axes_grid1/simple_axesgrid.md
Normal file
28
Python/matplotlab/gallery/axes_grid1/simple_axesgrid.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# 简单的轴线网格
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
|
||||
43
Python/matplotlab/gallery/axes_grid1/simple_axesgrid2.md
Normal file
43
Python/matplotlab/gallery/axes_grid1/simple_axesgrid2.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# 简单的轴线网格2
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
28
Python/matplotlab/gallery/axes_grid1/simple_axisline4.md
Normal file
28
Python/matplotlab/gallery/axes_grid1/simple_axisline4.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# 简单的 Axisline4
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
24
Python/matplotlab/gallery/axes_grid1/simple_colorbar.md
Normal file
24
Python/matplotlab/gallery/axes_grid1/simple_colorbar.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# 简单的彩色条实现
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
49
Python/matplotlab/gallery/axes_grid1/simple_rgb.md
Normal file
49
Python/matplotlab/gallery/axes_grid1/simple_rgb.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# 简单的 RGB
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,37 @@
|
||||
# 轴方向演示步骤01
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,48 @@
|
||||
# 轴方向演示步骤02
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,52 @@
|
||||
# 轴方向演示步骤03
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,65 @@
|
||||
# 轴方向演示步骤04
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
101
Python/matplotlab/gallery/axisartist/demo_axis_direction.md
Normal file
101
Python/matplotlab/gallery/axisartist/demo_axis_direction.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# 演示轴方向
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
37
Python/matplotlab/gallery/axisartist/demo_axisline_style.md
Normal file
37
Python/matplotlab/gallery/axisartist/demo_axisline_style.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# 轴线样式
|
||||
|
||||
此示例显示了轴样式的一些配置。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
142
Python/matplotlab/gallery/axisartist/demo_curvelinear_grid.md
Normal file
142
Python/matplotlab/gallery/axisartist/demo_curvelinear_grid.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# 演示Curvelinear网格
|
||||
|
||||
自定义网格和记号行。
|
||||
|
||||
此示例演示如何通过在网格上应用转换,使用GridHelperCurve线性来定义自定义网格和注释行。这可以用作第二个打印上的演示,用于在矩形框中创建极轴投影。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,75 @@
|
||||
# 演示Curvelinear网格2
|
||||
|
||||
自定义网格和记号行。
|
||||
|
||||
此示例演示如何通过在网格上应用转换,使用GridHelperCurve线性来定义自定义网格和注释行。作为打印上的演示,轴上将显示5x5矩阵。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
160
Python/matplotlab/gallery/axisartist/demo_floating_axes.md
Normal file
160
Python/matplotlab/gallery/axisartist/demo_floating_axes.md
Normal 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载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)
|
||||
76
Python/matplotlab/gallery/axisartist/demo_floating_axis.md
Normal file
76
Python/matplotlab/gallery/axisartist/demo_floating_axis.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# 演示浮动轴2
|
||||
|
||||
轴在矩形框内
|
||||
|
||||
以下代码演示了如何将浮动极坐标曲线放在矩形框内。 为了更好地了解极坐标曲线,请查看demo_curvelinear_grid.py。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
65
Python/matplotlab/gallery/axisartist/demo_parasite_axes.md
Normal file
65
Python/matplotlab/gallery/axisartist/demo_parasite_axes.md
Normal 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) 示例中。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
58
Python/matplotlab/gallery/axisartist/demo_parasite_axes2.md
Normal file
58
Python/matplotlab/gallery/axisartist/demo_parasite_axes2.md
Normal 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) 示例中。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,47 @@
|
||||
# Ticklabel对齐演示
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,47 @@
|
||||
# Ticklabel方向演示
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,26 @@
|
||||
# 简单轴方向01
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,41 @@
|
||||
# 简单轴方向03
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
114
Python/matplotlab/gallery/axisartist/simple_axis_pad.md
Normal file
114
Python/matplotlab/gallery/axisartist/simple_axis_pad.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# 简单的轴垫
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
32
Python/matplotlab/gallery/axisartist/simple_axisartist1.md
Normal file
32
Python/matplotlab/gallery/axisartist/simple_axisartist1.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# 简单的Axisartist1
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
45
Python/matplotlab/gallery/axisartist/simple_axisline.md
Normal file
45
Python/matplotlab/gallery/axisartist/simple_axisline.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# 简单的轴线
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
34
Python/matplotlab/gallery/axisartist/simple_axisline2.md
Normal file
34
Python/matplotlab/gallery/axisartist/simple_axisline2.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# 简单的轴线2
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
23
Python/matplotlab/gallery/axisartist/simple_axisline3.md
Normal file
23
Python/matplotlab/gallery/axisartist/simple_axisline3.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# 简单的轴线3
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
40
Python/matplotlab/gallery/color/color_by_yvalue.md
Normal file
40
Python/matplotlab/gallery/color/color_by_yvalue.md
Normal 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 参考
|
||||
|
||||
此示例中显示了以下函数,方法,类和模块的使用:
|
||||
|
||||
```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)
|
||||
60
Python/matplotlab/gallery/color/color_cycle_default.md
Normal file
60
Python/matplotlab/gallery/color/color_cycle_default.md
Normal 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 参考
|
||||
|
||||
此示例中显示了以下函数,方法,类和模块的使用:
|
||||
|
||||
```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)
|
||||
54
Python/matplotlab/gallery/color/color_cycler.md
Normal file
54
Python/matplotlab/gallery/color/color_cycler.md
Normal 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 参考
|
||||
|
||||
此示例中显示了以下函数,方法,类和模块的使用:
|
||||
|
||||
```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)
|
||||
68
Python/matplotlab/gallery/color/color_demo.md
Normal file
68
Python/matplotlab/gallery/color/color_demo.md
Normal 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 参考
|
||||
|
||||
此示例中显示了以下函数,方法,类和模块的使用:
|
||||
|
||||
```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)
|
||||
63
Python/matplotlab/gallery/color/colorbar_basics.md
Normal file
63
Python/matplotlab/gallery/color/colorbar_basics.md
Normal 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 参考
|
||||
|
||||
此示例中显示了以下函数,方法,类和模块的使用:
|
||||
|
||||
```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)
|
||||
96
Python/matplotlab/gallery/color/colormap_reference.md
Normal file
96
Python/matplotlab/gallery/color/colormap_reference.md
Normal 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 参考
|
||||
|
||||
此示例中显示了以下函数,方法,类和模块的使用:
|
||||
|
||||
```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)
|
||||
229
Python/matplotlab/gallery/color/custom_cmap.md
Normal file
229
Python/matplotlab/gallery/color/custom_cmap.md
Normal 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))}
|
||||
```
|
||||
|
||||
如果在这个例子中,r,g和b组件中没有不连续性,那么它很简单:上面每个元组的第二个和第三个元素是相同的 - 称之为“y”。 第一个元素(“x”)定义了0到1整个范围内的插值间隔,它必须跨越整个范围。换句话说,x的值将0到1范围划分为一组段,并且y给出每个段的端点颜色值。
|
||||
|
||||
现在考虑绿色。cdict['green']表示对于0 <= x <= 0.25,y为零; 没有绿色。0.25 < x <= 0.75,y从0到1线性变化.x > 0.75,y保持为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)
|
||||
```
|
||||
|
||||

|
||||
|
||||
--- 自定义色彩映射 ---
|
||||
|
||||
```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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 参考
|
||||
|
||||
此示例中显示了以下函数,方法,类和模块的使用:
|
||||
|
||||
```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)
|
||||
3
Python/matplotlab/gallery/color/index.md
Normal file
3
Python/matplotlab/gallery/color/index.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 颜色相关示例
|
||||
|
||||
有关matplotlib中可用的色彩映射的更深入信息及其属性的说明,请参阅[colormaps教程](https://matplotlib.org/tutorials/index.html#tutorials-colors)。
|
||||
106
Python/matplotlab/gallery/color/named_colors.md
Normal file
106
Python/matplotlab/gallery/color/named_colors.md
Normal 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()
|
||||
```
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 参考
|
||||
|
||||
此示例中显示了以下函数,方法,类和模块的使用:
|
||||
|
||||
```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)
|
||||
4
Python/matplotlab/gallery/download.md
Normal file
4
Python/matplotlab/gallery/download.md
Normal 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)
|
||||
24
Python/matplotlab/gallery/event_handling/close_event.md
Normal file
24
Python/matplotlab/gallery/event_handling/close_event.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# 关闭事件
|
||||
|
||||
显示图形关闭时发生的连接事件的示例。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
48
Python/matplotlab/gallery/event_handling/coords_demo.md
Normal file
48
Python/matplotlab/gallery/event_handling/coords_demo.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Coords 演示
|
||||
|
||||
如何通过连接到移动和单击事件来与绘图画布交互的示例
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
105
Python/matplotlab/gallery/event_handling/data_browser.md
Normal file
105
Python/matplotlab/gallery/event_handling/data_browser.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# 数据浏览器
|
||||
|
||||
在多个画布之间连接数据。
|
||||
|
||||
此示例介绍了如何与多个画布交互数据。这样,您可以选择并突出显示一个轴上的点,并在另一个轴上生成该点的数据。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
@@ -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)
|
||||
```
|
||||
|
||||

|
||||
|
||||
```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()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载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)
|
||||
@@ -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)
|
||||
@@ -0,0 +1,97 @@
|
||||
# 交互功能
|
||||
|
||||
这提供了交互功能的使用示例,例如ginput,waitforbuttonpress和手动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)
|
||||
@@ -0,0 +1,52 @@
|
||||
# 图像切片查看器
|
||||
|
||||
滚动三维阵列的二维图像切片。
|
||||
|
||||

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

|
||||
|
||||
```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)
|
||||
92
Python/matplotlab/gallery/event_handling/lasso_demo.md
Normal file
92
Python/matplotlab/gallery/event_handling/lasso_demo.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# 套索演示
|
||||
|
||||
演示如何使用套索选择一组点并获取所选点的索引。回调用于更改所选点的颜色。
|
||||
|
||||
这是一个概念验证实现(尽管它可以按原样使用)。将对API进行一些改进。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
55
Python/matplotlab/gallery/event_handling/legend_picking.md
Normal file
55
Python/matplotlab/gallery/event_handling/legend_picking.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# 图例选择
|
||||
|
||||
启用图例上的拾取以打开和关闭原始线。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
65
Python/matplotlab/gallery/event_handling/looking_glass.md
Normal file
65
Python/matplotlab/gallery/event_handling/looking_glass.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# 镜子
|
||||
|
||||
例如,使用鼠标事件模拟用于检查数据的镜子。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
164
Python/matplotlab/gallery/event_handling/path_editor.md
Normal file
164
Python/matplotlab/gallery/event_handling/path_editor.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# 路径编辑器
|
||||
|
||||
跨GUI共享事件。
|
||||
|
||||
此示例演示了使用Matplotlib事件处理与画布上的对象进行交互和修改对象的跨GUI应用程序。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
154
Python/matplotlab/gallery/event_handling/pick_event_demo.md
Normal file
154
Python/matplotlab/gallery/event_handling/pick_event_demo.md
Normal file
@@ -0,0 +1,154 @@
|
||||
# 选择事件演示
|
||||
|
||||
您可以通过设置艺术家的“选择器”属性来启用拾取(例如,matplotlib Line2D,Text,Patch,Polygon,AxesImage等...)
|
||||
|
||||
选择器属性有多种含义
|
||||
|
||||
- None - 此艺术家对象的选择功能已停用(默认)
|
||||
- boolean - 如果为True,则启用拾取,如果鼠标事件在艺术家上方,艺术家将触发拾取事件
|
||||
- float - 如果选择器是一个数字,则它被解释为以点为单位的epsilon容差,如果事件的数据在鼠标事件的epsilon内,则艺术家将触发事件。 对于某些艺术家(如线条和补丁集合),艺术家可能会为生成的挑选事件提供其他数据,例如,挑选事件的epsilon中的数据索引
|
||||
- function - 如果选择器是可调用的,则它是用户提供的函数,用于确定艺术家是否被鼠标事件命中。
|
||||
|
||||
hit, props = picker(artist, mouseevent)
|
||||
|
||||
确定命中测试。 如果鼠标事件在艺术家上方,则返回hit = True,props是要添加到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(显示空间中的坐标,如左下角的像素)和xdata,ydata(数据空间中的坐标)等属性。 此外,您可以获取有关按下哪些按钮,按下哪些键,鼠标所在的轴等的信息。有关详细信息,请参阅matplotlib.backend_bases.MouseEvent。
|
||||
|
||||
- artist - 生成pick事件的matplotlib.artist。
|
||||
|
||||
此外,某些艺术家(如Line2D和PatchCollection)可能会将其他元数据(如索引)附加到符合选择器条件的数据中(例如,行中指定的epsilon容差范围内的所有点)
|
||||
|
||||
以下示例说明了这些方法中的每一种。
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
```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)
|
||||
47
Python/matplotlab/gallery/event_handling/pick_event_demo2.md
Normal file
47
Python/matplotlab/gallery/event_handling/pick_event_demo2.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# 选择事件演示2
|
||||
|
||||
计算100个数据集的平均值和标准差(stddev),并绘制平均值vs stddev。单击其中一个mu,sigma点时,绘制生成均值和stddev的数据集中的原始数据。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
291
Python/matplotlab/gallery/event_handling/pipong.md
Normal file
291
Python/matplotlab/gallery/event_handling/pipong.md
Normal 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)
|
||||
187
Python/matplotlab/gallery/event_handling/poly_editor.md
Normal file
187
Python/matplotlab/gallery/event_handling/poly_editor.md
Normal file
@@ -0,0 +1,187 @@
|
||||
# 综合编辑器
|
||||
|
||||
这是一个示例,展示如何使用Matplotlib事件处理来构建跨GUI应用程序,以与画布上的对象进行交互。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
54
Python/matplotlab/gallery/event_handling/pong_sgskip.md
Normal file
54
Python/matplotlab/gallery/event_handling/pong_sgskip.md
Normal 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)
|
||||
73
Python/matplotlab/gallery/event_handling/resample.md
Normal file
73
Python/matplotlab/gallery/event_handling/resample.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# 重采样数据
|
||||
|
||||
下采样会降低信号的采样率或采样大小。在本教程中,当通过拖动和缩放调整打印时,将对信号进行缩减采样。
|
||||
|
||||

|
||||
|
||||
```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)
|
||||
40
Python/matplotlab/gallery/event_handling/timers.md
Normal file
40
Python/matplotlab/gallery/event_handling/timers.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# 计时器
|
||||
|
||||
使用通用计时器对象的简单示例。这用于更新图中标题的时间。
|
||||
|
||||

|
||||
|
||||
```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
Reference in New Issue
Block a user