mirror of
https://github.com/Estom/notes.git
synced 2026-04-14 02:10:47 +08:00
matplotlib & pandas
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
# 晕渲
|
||||
|
||||
用阴影图展示一些常见的技巧。
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.colors import LightSource, Normalize
|
||||
|
||||
|
||||
def display_colorbar():
|
||||
"""Display a correct numeric colorbar for a shaded plot."""
|
||||
y, x = np.mgrid[-4:2:200j, -4:2:200j]
|
||||
z = 10 * np.cos(x**2 + y**2)
|
||||
|
||||
cmap = plt.cm.copper
|
||||
ls = LightSource(315, 45)
|
||||
rgb = ls.shade(z, cmap)
|
||||
|
||||
fig, ax = plt.subplots()
|
||||
ax.imshow(rgb, interpolation='bilinear')
|
||||
|
||||
# Use a proxy artist for the colorbar...
|
||||
im = ax.imshow(z, cmap=cmap)
|
||||
im.remove()
|
||||
fig.colorbar(im)
|
||||
|
||||
ax.set_title('Using a colorbar with a shaded plot', size='x-large')
|
||||
|
||||
|
||||
def avoid_outliers():
|
||||
"""Use a custom norm to control the displayed z-range of a shaded plot."""
|
||||
y, x = np.mgrid[-4:2:200j, -4:2:200j]
|
||||
z = 10 * np.cos(x**2 + y**2)
|
||||
|
||||
# Add some outliers...
|
||||
z[100, 105] = 2000
|
||||
z[120, 110] = -9000
|
||||
|
||||
ls = LightSource(315, 45)
|
||||
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(8, 4.5))
|
||||
|
||||
rgb = ls.shade(z, plt.cm.copper)
|
||||
ax1.imshow(rgb, interpolation='bilinear')
|
||||
ax1.set_title('Full range of data')
|
||||
|
||||
rgb = ls.shade(z, plt.cm.copper, vmin=-10, vmax=10)
|
||||
ax2.imshow(rgb, interpolation='bilinear')
|
||||
ax2.set_title('Manually set range')
|
||||
|
||||
fig.suptitle('Avoiding Outliers in Shaded Plots', size='x-large')
|
||||
|
||||
|
||||
def shade_other_data():
|
||||
"""Demonstrates displaying different variables through shade and color."""
|
||||
y, x = np.mgrid[-4:2:200j, -4:2:200j]
|
||||
z1 = np.sin(x**2) # Data to hillshade
|
||||
z2 = np.cos(x**2 + y**2) # Data to color
|
||||
|
||||
norm = Normalize(z2.min(), z2.max())
|
||||
cmap = plt.cm.RdBu
|
||||
|
||||
ls = LightSource(315, 45)
|
||||
rgb = ls.shade_rgb(cmap(norm(z2)), z1)
|
||||
|
||||
fig, ax = plt.subplots()
|
||||
ax.imshow(rgb, interpolation='bilinear')
|
||||
ax.set_title('Shade by one variable, color by another', size='x-large')
|
||||
|
||||
display_colorbar()
|
||||
avoid_outliers()
|
||||
shade_other_data()
|
||||
plt.show()
|
||||
```
|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载python源码: advanced_hillshading.py](https://matplotlib.org/_downloads/advanced_hillshading.py)
|
||||
- [下载Jupyter notebook: advanced_hillshading.ipynb](https://matplotlib.org/_downloads/advanced_hillshading.ipynb)
|
||||
78
Python/matplotlab/gallery/specialty_plots/anscombe.md
Normal file
78
Python/matplotlab/gallery/specialty_plots/anscombe.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Anscombe的四重奏
|
||||
|
||||

|
||||
|
||||
输出:
|
||||
|
||||
```python
|
||||
mean=7.50, std=1.94, r=0.82
|
||||
mean=7.50, std=1.94, r=0.82
|
||||
mean=7.50, std=1.94, r=0.82
|
||||
mean=7.50, std=1.94, r=0.82
|
||||
```
|
||||
|
||||
```python
|
||||
"""
|
||||
Edward Tufte uses this example from Anscombe to show 4 datasets of x
|
||||
and y that have the same mean, standard deviation, and regression
|
||||
line, but which are qualitatively different.
|
||||
|
||||
matplotlib fun for a rainy day
|
||||
"""
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
x = np.array([10, 8, 13, 9, 11, 14, 6, 4, 12, 7, 5])
|
||||
y1 = np.array([8.04, 6.95, 7.58, 8.81, 8.33, 9.96, 7.24, 4.26, 10.84, 4.82, 5.68])
|
||||
y2 = np.array([9.14, 8.14, 8.74, 8.77, 9.26, 8.10, 6.13, 3.10, 9.13, 7.26, 4.74])
|
||||
y3 = np.array([7.46, 6.77, 12.74, 7.11, 7.81, 8.84, 6.08, 5.39, 8.15, 6.42, 5.73])
|
||||
x4 = np.array([8, 8, 8, 8, 8, 8, 8, 19, 8, 8, 8])
|
||||
y4 = np.array([6.58, 5.76, 7.71, 8.84, 8.47, 7.04, 5.25, 12.50, 5.56, 7.91, 6.89])
|
||||
|
||||
|
||||
def fit(x):
|
||||
return 3 + 0.5 * x
|
||||
|
||||
|
||||
xfit = np.array([np.min(x), np.max(x)])
|
||||
|
||||
plt.subplot(221)
|
||||
plt.plot(x, y1, 'ks', xfit, fit(xfit), 'r-', lw=2)
|
||||
plt.axis([2, 20, 2, 14])
|
||||
plt.setp(plt.gca(), xticklabels=[], yticks=(4, 8, 12), xticks=(0, 10, 20))
|
||||
plt.text(3, 12, 'I', fontsize=20)
|
||||
|
||||
plt.subplot(222)
|
||||
plt.plot(x, y2, 'ks', xfit, fit(xfit), 'r-', lw=2)
|
||||
plt.axis([2, 20, 2, 14])
|
||||
plt.setp(plt.gca(), xticks=(0, 10, 20), xticklabels=[],
|
||||
yticks=(4, 8, 12), yticklabels=[], )
|
||||
plt.text(3, 12, 'II', fontsize=20)
|
||||
|
||||
plt.subplot(223)
|
||||
plt.plot(x, y3, 'ks', xfit, fit(xfit), 'r-', lw=2)
|
||||
plt.axis([2, 20, 2, 14])
|
||||
plt.text(3, 12, 'III', fontsize=20)
|
||||
plt.setp(plt.gca(), yticks=(4, 8, 12), xticks=(0, 10, 20))
|
||||
|
||||
plt.subplot(224)
|
||||
xfit = np.array([np.min(x4), np.max(x4)])
|
||||
plt.plot(x4, y4, 'ks', xfit, fit(xfit), 'r-', lw=2)
|
||||
plt.axis([2, 20, 2, 14])
|
||||
plt.setp(plt.gca(), yticklabels=[], yticks=(4, 8, 12), xticks=(0, 10, 20))
|
||||
plt.text(3, 12, 'IV', fontsize=20)
|
||||
|
||||
# verify the stats
|
||||
pairs = (x, y1), (x, y2), (x, y3), (x4, y4)
|
||||
for x, y in pairs:
|
||||
print('mean=%1.2f, std=%1.2f, r=%1.2f' % (np.mean(y), np.std(y),
|
||||
np.corrcoef(x, y)[0][1]))
|
||||
|
||||
plt.show()
|
||||
```
|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载python源码: anscombe.py](https://matplotlib.org/_downloads/anscombe.py)
|
||||
- [下载Jupyter notebook: anscombe.ipynb](https://matplotlib.org/_downloads/anscombe.ipynb)
|
||||
48
Python/matplotlab/gallery/specialty_plots/hinton_demo.md
Normal file
48
Python/matplotlab/gallery/specialty_plots/hinton_demo.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Hinton图
|
||||
|
||||
Hinton图对于可视化2D阵列的值(例如,权重矩阵)是有用的:正值和负值分别由白色和黑色方块表示,并且每个方块的大小表示每个值的大小。
|
||||
|
||||
David Warde-Farley在SciPy Cookbook上的初步想法
|
||||
|
||||

|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
def hinton(matrix, max_weight=None, ax=None):
|
||||
"""Draw Hinton diagram for visualizing a weight matrix."""
|
||||
ax = ax if ax is not None else plt.gca()
|
||||
|
||||
if not max_weight:
|
||||
max_weight = 2 ** np.ceil(np.log(np.abs(matrix).max()) / np.log(2))
|
||||
|
||||
ax.patch.set_facecolor('gray')
|
||||
ax.set_aspect('equal', 'box')
|
||||
ax.xaxis.set_major_locator(plt.NullLocator())
|
||||
ax.yaxis.set_major_locator(plt.NullLocator())
|
||||
|
||||
for (x, y), w in np.ndenumerate(matrix):
|
||||
color = 'white' if w > 0 else 'black'
|
||||
size = np.sqrt(np.abs(w) / max_weight)
|
||||
rect = plt.Rectangle([x - size / 2, y - size / 2], size, size,
|
||||
facecolor=color, edgecolor=color)
|
||||
ax.add_patch(rect)
|
||||
|
||||
ax.autoscale_view()
|
||||
ax.invert_yaxis()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Fixing random state for reproducibility
|
||||
np.random.seed(19680801)
|
||||
|
||||
hinton(np.random.rand(20, 20) - 0.5)
|
||||
plt.show()
|
||||
```
|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载python源码: hinton_demo.py](https://matplotlib.org/_downloads/hinton_demo.py)
|
||||
- [下载Jupyter notebook: hinton_demo.ipynb](https://matplotlib.org/_downloads/hinton_demo.ipynb)
|
||||
@@ -0,0 +1,214 @@
|
||||
# 左心室靶心
|
||||
|
||||
该示例演示了如何为美国心脏协会(AHA)推荐的左心室创建17段模型。
|
||||
|
||||

|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
import matplotlib as mpl
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
def bullseye_plot(ax, data, segBold=None, cmap=None, norm=None):
|
||||
"""
|
||||
Bullseye representation for the left ventricle.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ax : axes
|
||||
data : list of int and float
|
||||
The intensity values for each of the 17 segments
|
||||
segBold: list of int, optional
|
||||
A list with the segments to highlight
|
||||
cmap : ColorMap or None, optional
|
||||
Optional argument to set the desired colormap
|
||||
norm : Normalize or None, optional
|
||||
Optional argument to normalize data into the [0.0, 1.0] range
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
This function create the 17 segment model for the left ventricle according
|
||||
to the American Heart Association (AHA) [1]_
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] M. D. Cerqueira, N. J. Weissman, V. Dilsizian, A. K. Jacobs,
|
||||
S. Kaul, W. K. Laskey, D. J. Pennell, J. A. Rumberger, T. Ryan,
|
||||
and M. S. Verani, "Standardized myocardial segmentation and
|
||||
nomenclature for tomographic imaging of the heart",
|
||||
Circulation, vol. 105, no. 4, pp. 539-542, 2002.
|
||||
"""
|
||||
if segBold is None:
|
||||
segBold = []
|
||||
|
||||
linewidth = 2
|
||||
data = np.array(data).ravel()
|
||||
|
||||
if cmap is None:
|
||||
cmap = plt.cm.viridis
|
||||
|
||||
if norm is None:
|
||||
norm = mpl.colors.Normalize(vmin=data.min(), vmax=data.max())
|
||||
|
||||
theta = np.linspace(0, 2 * np.pi, 768)
|
||||
r = np.linspace(0.2, 1, 4)
|
||||
|
||||
# Create the bound for the segment 17
|
||||
for i in range(r.shape[0]):
|
||||
ax.plot(theta, np.repeat(r[i], theta.shape), '-k', lw=linewidth)
|
||||
|
||||
# Create the bounds for the segments 1-12
|
||||
for i in range(6):
|
||||
theta_i = np.deg2rad(i * 60)
|
||||
ax.plot([theta_i, theta_i], [r[1], 1], '-k', lw=linewidth)
|
||||
|
||||
# Create the bounds for the segments 13-16
|
||||
for i in range(4):
|
||||
theta_i = np.deg2rad(i * 90 - 45)
|
||||
ax.plot([theta_i, theta_i], [r[0], r[1]], '-k', lw=linewidth)
|
||||
|
||||
# Fill the segments 1-6
|
||||
r0 = r[2:4]
|
||||
r0 = np.repeat(r0[:, np.newaxis], 128, axis=1).T
|
||||
for i in range(6):
|
||||
# First segment start at 60 degrees
|
||||
theta0 = theta[i * 128:i * 128 + 128] + np.deg2rad(60)
|
||||
theta0 = np.repeat(theta0[:, np.newaxis], 2, axis=1)
|
||||
z = np.ones((128, 2)) * data[i]
|
||||
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
|
||||
if i + 1 in segBold:
|
||||
ax.plot(theta0, r0, '-k', lw=linewidth + 2)
|
||||
ax.plot(theta0[0], [r[2], r[3]], '-k', lw=linewidth + 1)
|
||||
ax.plot(theta0[-1], [r[2], r[3]], '-k', lw=linewidth + 1)
|
||||
|
||||
# Fill the segments 7-12
|
||||
r0 = r[1:3]
|
||||
r0 = np.repeat(r0[:, np.newaxis], 128, axis=1).T
|
||||
for i in range(6):
|
||||
# First segment start at 60 degrees
|
||||
theta0 = theta[i * 128:i * 128 + 128] + np.deg2rad(60)
|
||||
theta0 = np.repeat(theta0[:, np.newaxis], 2, axis=1)
|
||||
z = np.ones((128, 2)) * data[i + 6]
|
||||
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
|
||||
if i + 7 in segBold:
|
||||
ax.plot(theta0, r0, '-k', lw=linewidth + 2)
|
||||
ax.plot(theta0[0], [r[1], r[2]], '-k', lw=linewidth + 1)
|
||||
ax.plot(theta0[-1], [r[1], r[2]], '-k', lw=linewidth + 1)
|
||||
|
||||
# Fill the segments 13-16
|
||||
r0 = r[0:2]
|
||||
r0 = np.repeat(r0[:, np.newaxis], 192, axis=1).T
|
||||
for i in range(4):
|
||||
# First segment start at 45 degrees
|
||||
theta0 = theta[i * 192:i * 192 + 192] + np.deg2rad(45)
|
||||
theta0 = np.repeat(theta0[:, np.newaxis], 2, axis=1)
|
||||
z = np.ones((192, 2)) * data[i + 12]
|
||||
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
|
||||
if i + 13 in segBold:
|
||||
ax.plot(theta0, r0, '-k', lw=linewidth + 2)
|
||||
ax.plot(theta0[0], [r[0], r[1]], '-k', lw=linewidth + 1)
|
||||
ax.plot(theta0[-1], [r[0], r[1]], '-k', lw=linewidth + 1)
|
||||
|
||||
# Fill the segments 17
|
||||
if data.size == 17:
|
||||
r0 = np.array([0, r[0]])
|
||||
r0 = np.repeat(r0[:, np.newaxis], theta.size, axis=1).T
|
||||
theta0 = np.repeat(theta[:, np.newaxis], 2, axis=1)
|
||||
z = np.ones((theta.size, 2)) * data[16]
|
||||
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
|
||||
if 17 in segBold:
|
||||
ax.plot(theta0, r0, '-k', lw=linewidth + 2)
|
||||
|
||||
ax.set_ylim([0, 1])
|
||||
ax.set_yticklabels([])
|
||||
ax.set_xticklabels([])
|
||||
|
||||
|
||||
# Create the fake data
|
||||
data = np.array(range(17)) + 1
|
||||
|
||||
|
||||
# Make a figure and axes with dimensions as desired.
|
||||
fig, ax = plt.subplots(figsize=(12, 8), nrows=1, ncols=3,
|
||||
subplot_kw=dict(projection='polar'))
|
||||
fig.canvas.set_window_title('Left Ventricle Bulls Eyes (AHA)')
|
||||
|
||||
# Create the axis for the colorbars
|
||||
axl = fig.add_axes([0.14, 0.15, 0.2, 0.05])
|
||||
axl2 = fig.add_axes([0.41, 0.15, 0.2, 0.05])
|
||||
axl3 = fig.add_axes([0.69, 0.15, 0.2, 0.05])
|
||||
|
||||
|
||||
# Set the colormap and norm to correspond to the data for which
|
||||
# the colorbar will be used.
|
||||
cmap = mpl.cm.viridis
|
||||
norm = mpl.colors.Normalize(vmin=1, vmax=17)
|
||||
|
||||
# ColorbarBase derives from ScalarMappable and puts a colorbar
|
||||
# in a specified axes, so it has everything needed for a
|
||||
# standalone colorbar. There are many more kwargs, but the
|
||||
# following gives a basic continuous colorbar with ticks
|
||||
# and labels.
|
||||
cb1 = mpl.colorbar.ColorbarBase(axl, cmap=cmap, norm=norm,
|
||||
orientation='horizontal')
|
||||
cb1.set_label('Some Units')
|
||||
|
||||
|
||||
# Set the colormap and norm to correspond to the data for which
|
||||
# the colorbar will be used.
|
||||
cmap2 = mpl.cm.cool
|
||||
norm2 = mpl.colors.Normalize(vmin=1, vmax=17)
|
||||
|
||||
# ColorbarBase derives from ScalarMappable and puts a colorbar
|
||||
# in a specified axes, so it has everything needed for a
|
||||
# standalone colorbar. There are many more kwargs, but the
|
||||
# following gives a basic continuous colorbar with ticks
|
||||
# and labels.
|
||||
cb2 = mpl.colorbar.ColorbarBase(axl2, cmap=cmap2, norm=norm2,
|
||||
orientation='horizontal')
|
||||
cb2.set_label('Some other units')
|
||||
|
||||
|
||||
# The second example illustrates the use of a ListedColormap, a
|
||||
# BoundaryNorm, and extended ends to show the "over" and "under"
|
||||
# value colors.
|
||||
cmap3 = mpl.colors.ListedColormap(['r', 'g', 'b', 'c'])
|
||||
cmap3.set_over('0.35')
|
||||
cmap3.set_under('0.75')
|
||||
|
||||
# If a 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.
|
||||
bounds = [2, 3, 7, 9, 15]
|
||||
norm3 = mpl.colors.BoundaryNorm(bounds, cmap3.N)
|
||||
cb3 = mpl.colorbar.ColorbarBase(axl3, cmap=cmap3, norm=norm3,
|
||||
# to use 'extend', you must
|
||||
# specify two extra boundaries:
|
||||
boundaries=[0] + bounds + [18],
|
||||
extend='both',
|
||||
ticks=bounds, # optional
|
||||
spacing='proportional',
|
||||
orientation='horizontal')
|
||||
cb3.set_label('Discrete intervals, some other units')
|
||||
|
||||
|
||||
# Create the 17 segment model
|
||||
bullseye_plot(ax[0], data, cmap=cmap, norm=norm)
|
||||
ax[0].set_title('Bulls Eye (AHA)')
|
||||
|
||||
bullseye_plot(ax[1], data, cmap=cmap2, norm=norm2)
|
||||
ax[1].set_title('Bulls Eye (AHA)')
|
||||
|
||||
bullseye_plot(ax[2], data, segBold=[3, 5, 6, 11, 12, 16],
|
||||
cmap=cmap3, norm=norm3)
|
||||
ax[2].set_title('Segments [3,5,6,11,12,16] in bold')
|
||||
|
||||
plt.show()
|
||||
```
|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载python源码: leftventricle_bulleye.py](https://matplotlib.org/_downloads/leftventricle_bulleye.py)
|
||||
- [下载Jupyter notebook: leftventricle_bulleye.ipynb](https://matplotlib.org/_downloads/leftventricle_bulleye.ipynb)
|
||||
28
Python/matplotlab/gallery/specialty_plots/mri_demo.md
Normal file
28
Python/matplotlab/gallery/specialty_plots/mri_demo.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# MRI
|
||||
|
||||
此示例说明如何将(MRI)图像读入NumPy阵列,并使用imshow以灰度显示。
|
||||
|
||||

|
||||
|
||||
```python
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.cbook as cbook
|
||||
import matplotlib.cm as cm
|
||||
import numpy as np
|
||||
|
||||
|
||||
# Data are 256x256 16 bit integers
|
||||
with cbook.get_sample_data('s1045.ima.gz') as dfile:
|
||||
im = np.fromstring(dfile.read(), np.uint16).reshape((256, 256))
|
||||
|
||||
fig, ax = plt.subplots(num="MRI_demo")
|
||||
ax.imshow(im, cmap=cm.gray)
|
||||
ax.axis('off')
|
||||
|
||||
plt.show()
|
||||
```
|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载python源码: mri_demo.py](https://matplotlib.org/_downloads/mri_demo.py)
|
||||
- [下载Jupyter notebook: mri_demo.ipynb](https://matplotlib.org/_downloads/mri_demo.ipynb)
|
||||
82
Python/matplotlab/gallery/specialty_plots/mri_with_eeg.md
Normal file
82
Python/matplotlab/gallery/specialty_plots/mri_with_eeg.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# MRI与脑电图
|
||||
|
||||
显示一组带有MRI图像的子图,其强度直方图和一些EEG轨迹。
|
||||
|
||||

|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.cbook as cbook
|
||||
import matplotlib.cm as cm
|
||||
|
||||
from matplotlib.collections import LineCollection
|
||||
from matplotlib.ticker import MultipleLocator
|
||||
|
||||
fig = plt.figure("MRI_with_EEG")
|
||||
|
||||
# Load the MRI data (256x256 16 bit integers)
|
||||
with cbook.get_sample_data('s1045.ima.gz') as dfile:
|
||||
im = np.fromstring(dfile.read(), np.uint16).reshape((256, 256))
|
||||
|
||||
# Plot the MRI image
|
||||
ax0 = fig.add_subplot(2, 2, 1)
|
||||
ax0.imshow(im, cmap=cm.gray)
|
||||
ax0.axis('off')
|
||||
|
||||
# Plot the histogram of MRI intensity
|
||||
ax1 = fig.add_subplot(2, 2, 2)
|
||||
im = np.ravel(im)
|
||||
im = im[np.nonzero(im)] # Ignore the background
|
||||
im = im / (2**16 - 1) # Normalize
|
||||
ax1.hist(im, bins=100)
|
||||
ax1.xaxis.set_major_locator(MultipleLocator(0.4))
|
||||
ax1.minorticks_on()
|
||||
ax1.set_yticks([])
|
||||
ax1.set_xlabel('Intensity (a.u.)')
|
||||
ax1.set_ylabel('MRI density')
|
||||
|
||||
# Load the EEG data
|
||||
n_samples, n_rows = 800, 4
|
||||
with cbook.get_sample_data('eeg.dat') as eegfile:
|
||||
data = np.fromfile(eegfile, dtype=float).reshape((n_samples, n_rows))
|
||||
t = 10 * np.arange(n_samples) / n_samples
|
||||
|
||||
# Plot the EEG
|
||||
ticklocs = []
|
||||
ax2 = fig.add_subplot(2, 1, 2)
|
||||
ax2.set_xlim(0, 10)
|
||||
ax2.set_xticks(np.arange(10))
|
||||
dmin = data.min()
|
||||
dmax = data.max()
|
||||
dr = (dmax - dmin) * 0.7 # Crowd them a bit.
|
||||
y0 = dmin
|
||||
y1 = (n_rows - 1) * dr + dmax
|
||||
ax2.set_ylim(y0, y1)
|
||||
|
||||
segs = []
|
||||
for i in range(n_rows):
|
||||
segs.append(np.column_stack((t, data[:, i])))
|
||||
ticklocs.append(i * dr)
|
||||
|
||||
offsets = np.zeros((n_rows, 2), dtype=float)
|
||||
offsets[:, 1] = ticklocs
|
||||
|
||||
lines = LineCollection(segs, offsets=offsets, transOffset=None)
|
||||
ax2.add_collection(lines)
|
||||
|
||||
# Set the yticks to use axes coordinates on the y axis
|
||||
ax2.set_yticks(ticklocs)
|
||||
ax2.set_yticklabels(['PG3', 'PG5', 'PG7', 'PG9'])
|
||||
|
||||
ax2.set_xlabel('Time (s)')
|
||||
|
||||
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
```
|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载python源码: mri_with_eeg.py](https://matplotlib.org/_downloads/mri_with_eeg.py)
|
||||
- [下载Jupyter notebook: mri_with_eeg.ipynb](https://matplotlib.org/_downloads/mri_with_eeg.ipynb)
|
||||
222
Python/matplotlab/gallery/specialty_plots/radar_chart.md
Normal file
222
Python/matplotlab/gallery/specialty_plots/radar_chart.md
Normal file
@@ -0,0 +1,222 @@
|
||||
# 雷达图(又名蜘蛛星图)
|
||||
|
||||
此示例创建雷达图表,也称为蜘蛛星图。
|
||||
|
||||
虽然此示例允许“圆”或“多边形”的框架,但多边形框架没有合适的网格线(线条是圆形而不是多边形)。 通过将matplotlib.axis中的GRIDLINE_INTERPOLATION_STEPS设置为所需的顶点数,可以获得多边形网格,但多边形的方向不与径向轴对齐。
|
||||
|
||||
http://en.wikipedia.org/wiki/Radar_chart
|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.path import Path
|
||||
from matplotlib.spines import Spine
|
||||
from matplotlib.projections.polar import PolarAxes
|
||||
from matplotlib.projections import register_projection
|
||||
|
||||
|
||||
def radar_factory(num_vars, frame='circle'):
|
||||
"""Create a radar chart with `num_vars` axes.
|
||||
|
||||
This function creates a RadarAxes projection and registers it.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
num_vars : int
|
||||
Number of variables for radar chart.
|
||||
frame : {'circle' | 'polygon'}
|
||||
Shape of frame surrounding axes.
|
||||
|
||||
"""
|
||||
# calculate evenly-spaced axis angles
|
||||
theta = np.linspace(0, 2*np.pi, num_vars, endpoint=False)
|
||||
|
||||
def draw_poly_patch(self):
|
||||
# rotate theta such that the first axis is at the top
|
||||
verts = unit_poly_verts(theta + np.pi / 2)
|
||||
return plt.Polygon(verts, closed=True, edgecolor='k')
|
||||
|
||||
def draw_circle_patch(self):
|
||||
# unit circle centered on (0.5, 0.5)
|
||||
return plt.Circle((0.5, 0.5), 0.5)
|
||||
|
||||
patch_dict = {'polygon': draw_poly_patch, 'circle': draw_circle_patch}
|
||||
if frame not in patch_dict:
|
||||
raise ValueError('unknown value for `frame`: %s' % frame)
|
||||
|
||||
class RadarAxes(PolarAxes):
|
||||
|
||||
name = 'radar'
|
||||
# use 1 line segment to connect specified points
|
||||
RESOLUTION = 1
|
||||
# define draw_frame method
|
||||
draw_patch = patch_dict[frame]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
# rotate plot such that the first axis is at the top
|
||||
self.set_theta_zero_location('N')
|
||||
|
||||
def fill(self, *args, closed=True, **kwargs):
|
||||
"""Override fill so that line is closed by default"""
|
||||
return super().fill(closed=closed, *args, **kwargs)
|
||||
|
||||
def plot(self, *args, **kwargs):
|
||||
"""Override plot so that line is closed by default"""
|
||||
lines = super().plot(*args, **kwargs)
|
||||
for line in lines:
|
||||
self._close_line(line)
|
||||
|
||||
def _close_line(self, line):
|
||||
x, y = line.get_data()
|
||||
# FIXME: markers at x[0], y[0] get doubled-up
|
||||
if x[0] != x[-1]:
|
||||
x = np.concatenate((x, [x[0]]))
|
||||
y = np.concatenate((y, [y[0]]))
|
||||
line.set_data(x, y)
|
||||
|
||||
def set_varlabels(self, labels):
|
||||
self.set_thetagrids(np.degrees(theta), labels)
|
||||
|
||||
def _gen_axes_patch(self):
|
||||
return self.draw_patch()
|
||||
|
||||
def _gen_axes_spines(self):
|
||||
if frame == 'circle':
|
||||
return super()._gen_axes_spines()
|
||||
# The following is a hack to get the spines (i.e. the axes frame)
|
||||
# to draw correctly for a polygon frame.
|
||||
|
||||
# spine_type must be 'left', 'right', 'top', 'bottom', or `circle`.
|
||||
spine_type = 'circle'
|
||||
verts = unit_poly_verts(theta + np.pi / 2)
|
||||
# close off polygon by repeating first vertex
|
||||
verts.append(verts[0])
|
||||
path = Path(verts)
|
||||
|
||||
spine = Spine(self, spine_type, path)
|
||||
spine.set_transform(self.transAxes)
|
||||
return {'polar': spine}
|
||||
|
||||
register_projection(RadarAxes)
|
||||
return theta
|
||||
|
||||
|
||||
def unit_poly_verts(theta):
|
||||
"""Return vertices of polygon for subplot axes.
|
||||
|
||||
This polygon is circumscribed by a unit circle centered at (0.5, 0.5)
|
||||
"""
|
||||
x0, y0, r = [0.5] * 3
|
||||
verts = [(r*np.cos(t) + x0, r*np.sin(t) + y0) for t in theta]
|
||||
return verts
|
||||
|
||||
|
||||
def example_data():
|
||||
# The following data is from the Denver Aerosol Sources and Health study.
|
||||
# See doi:10.1016/j.atmosenv.2008.12.017
|
||||
#
|
||||
# The data are pollution source profile estimates for five modeled
|
||||
# pollution sources (e.g., cars, wood-burning, etc) that emit 7-9 chemical
|
||||
# species. The radar charts are experimented with here to see if we can
|
||||
# nicely visualize how the modeled source profiles change across four
|
||||
# scenarios:
|
||||
# 1) No gas-phase species present, just seven particulate counts on
|
||||
# Sulfate
|
||||
# Nitrate
|
||||
# Elemental Carbon (EC)
|
||||
# Organic Carbon fraction 1 (OC)
|
||||
# Organic Carbon fraction 2 (OC2)
|
||||
# Organic Carbon fraction 3 (OC3)
|
||||
# Pyrolized Organic Carbon (OP)
|
||||
# 2)Inclusion of gas-phase specie carbon monoxide (CO)
|
||||
# 3)Inclusion of gas-phase specie ozone (O3).
|
||||
# 4)Inclusion of both gas-phase species is present...
|
||||
data = [
|
||||
['Sulfate', 'Nitrate', 'EC', 'OC1', 'OC2', 'OC3', 'OP', 'CO', 'O3'],
|
||||
('Basecase', [
|
||||
[0.88, 0.01, 0.03, 0.03, 0.00, 0.06, 0.01, 0.00, 0.00],
|
||||
[0.07, 0.95, 0.04, 0.05, 0.00, 0.02, 0.01, 0.00, 0.00],
|
||||
[0.01, 0.02, 0.85, 0.19, 0.05, 0.10, 0.00, 0.00, 0.00],
|
||||
[0.02, 0.01, 0.07, 0.01, 0.21, 0.12, 0.98, 0.00, 0.00],
|
||||
[0.01, 0.01, 0.02, 0.71, 0.74, 0.70, 0.00, 0.00, 0.00]]),
|
||||
('With CO', [
|
||||
[0.88, 0.02, 0.02, 0.02, 0.00, 0.05, 0.00, 0.05, 0.00],
|
||||
[0.08, 0.94, 0.04, 0.02, 0.00, 0.01, 0.12, 0.04, 0.00],
|
||||
[0.01, 0.01, 0.79, 0.10, 0.00, 0.05, 0.00, 0.31, 0.00],
|
||||
[0.00, 0.02, 0.03, 0.38, 0.31, 0.31, 0.00, 0.59, 0.00],
|
||||
[0.02, 0.02, 0.11, 0.47, 0.69, 0.58, 0.88, 0.00, 0.00]]),
|
||||
('With O3', [
|
||||
[0.89, 0.01, 0.07, 0.00, 0.00, 0.05, 0.00, 0.00, 0.03],
|
||||
[0.07, 0.95, 0.05, 0.04, 0.00, 0.02, 0.12, 0.00, 0.00],
|
||||
[0.01, 0.02, 0.86, 0.27, 0.16, 0.19, 0.00, 0.00, 0.00],
|
||||
[0.01, 0.03, 0.00, 0.32, 0.29, 0.27, 0.00, 0.00, 0.95],
|
||||
[0.02, 0.00, 0.03, 0.37, 0.56, 0.47, 0.87, 0.00, 0.00]]),
|
||||
('CO & O3', [
|
||||
[0.87, 0.01, 0.08, 0.00, 0.00, 0.04, 0.00, 0.00, 0.01],
|
||||
[0.09, 0.95, 0.02, 0.03, 0.00, 0.01, 0.13, 0.06, 0.00],
|
||||
[0.01, 0.02, 0.71, 0.24, 0.13, 0.16, 0.00, 0.50, 0.00],
|
||||
[0.01, 0.03, 0.00, 0.28, 0.24, 0.23, 0.00, 0.44, 0.88],
|
||||
[0.02, 0.00, 0.18, 0.45, 0.64, 0.55, 0.86, 0.00, 0.16]])
|
||||
]
|
||||
return data
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
N = 9
|
||||
theta = radar_factory(N, frame='polygon')
|
||||
|
||||
data = example_data()
|
||||
spoke_labels = data.pop(0)
|
||||
|
||||
fig, axes = plt.subplots(figsize=(9, 9), nrows=2, ncols=2,
|
||||
subplot_kw=dict(projection='radar'))
|
||||
fig.subplots_adjust(wspace=0.25, hspace=0.20, top=0.85, bottom=0.05)
|
||||
|
||||
colors = ['b', 'r', 'g', 'm', 'y']
|
||||
# Plot the four cases from the example data on separate axes
|
||||
for ax, (title, case_data) in zip(axes.flatten(), data):
|
||||
ax.set_rgrids([0.2, 0.4, 0.6, 0.8])
|
||||
ax.set_title(title, weight='bold', size='medium', position=(0.5, 1.1),
|
||||
horizontalalignment='center', verticalalignment='center')
|
||||
for d, color in zip(case_data, colors):
|
||||
ax.plot(theta, d, color=color)
|
||||
ax.fill(theta, d, facecolor=color, alpha=0.25)
|
||||
ax.set_varlabels(spoke_labels)
|
||||
|
||||
# add legend relative to top-left plot
|
||||
ax = axes[0, 0]
|
||||
labels = ('Factor 1', 'Factor 2', 'Factor 3', 'Factor 4', 'Factor 5')
|
||||
legend = ax.legend(labels, loc=(0.9, .95),
|
||||
labelspacing=0.1, fontsize='small')
|
||||
|
||||
fig.text(0.5, 0.965, '5-Factor Solution Profiles Across Four Scenarios',
|
||||
horizontalalignment='center', color='black', weight='bold',
|
||||
size='large')
|
||||
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 参考
|
||||
|
||||
此示例中显示了以下函数,方法,类和模块的使用:
|
||||
|
||||
```python
|
||||
import matplotlib
|
||||
matplotlib.path
|
||||
matplotlib.path.Path
|
||||
matplotlib.spines
|
||||
matplotlib.spines.Spine
|
||||
matplotlib.projections
|
||||
matplotlib.projections.polar
|
||||
matplotlib.projections.polar.PolarAxes
|
||||
matplotlib.projections.register_projection
|
||||
```
|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载python源码: radar_chart.py](https://matplotlib.org/_downloads/radar_chart.py)
|
||||
- [下载Jupyter notebook: radar_chart.ipynb](https://matplotlib.org/_downloads/radar_chart.ipynb)
|
||||
93
Python/matplotlab/gallery/specialty_plots/sankey_basics.md
Normal file
93
Python/matplotlab/gallery/specialty_plots/sankey_basics.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# 桑基图类
|
||||
|
||||
通过生成三个基本图表来演示Sankey类。
|
||||
|
||||
```python
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from matplotlib.sankey import Sankey
|
||||
```
|
||||
|
||||
示例1 - 主要是默认值
|
||||
|
||||
这演示了如何通过隐式调用Sankey.add()方法并将finish()附加到类的调用来创建一个简单的图。
|
||||
|
||||
```python
|
||||
Sankey(flows=[0.25, 0.15, 0.60, -0.20, -0.15, -0.05, -0.50, -0.10],
|
||||
labels=['', '', '', 'First', 'Second', 'Third', 'Fourth', 'Fifth'],
|
||||
orientations=[-1, 1, 0, 1, 1, 1, 0, -1]).finish()
|
||||
plt.title("The default settings produce a diagram like this.")
|
||||
```
|
||||
|
||||

|
||||
|
||||
注意:
|
||||
|
||||
示例2
|
||||
|
||||
这表明:
|
||||
|
||||
```python
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(1, 1, 1, xticks=[], yticks=[],
|
||||
title="Flow Diagram of a Widget")
|
||||
sankey = Sankey(ax=ax, scale=0.01, offset=0.2, head_angle=180,
|
||||
format='%.0f', unit='%')
|
||||
sankey.add(flows=[25, 0, 60, -10, -20, -5, -15, -10, -40],
|
||||
labels=['', '', '', 'First', 'Second', 'Third', 'Fourth',
|
||||
'Fifth', 'Hurray!'],
|
||||
orientations=[-1, 1, 0, 1, 1, 1, -1, -1, 0],
|
||||
pathlengths=[0.25, 0.25, 0.25, 0.25, 0.25, 0.6, 0.25, 0.25,
|
||||
0.25],
|
||||
patchlabel="Widget\nA") # Arguments to matplotlib.patches.PathPatch()
|
||||
diagrams = sankey.finish()
|
||||
diagrams[0].texts[-1].set_color('r')
|
||||
diagrams[0].text.set_fontweight('bold')
|
||||
```
|
||||
|
||||

|
||||
|
||||
注意:
|
||||
|
||||
示例3
|
||||
|
||||
这表明:
|
||||
|
||||
```python
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(1, 1, 1, xticks=[], yticks=[], title="Two Systems")
|
||||
flows = [0.25, 0.15, 0.60, -0.10, -0.05, -0.25, -0.15, -0.10, -0.35]
|
||||
sankey = Sankey(ax=ax, unit=None)
|
||||
sankey.add(flows=flows, label='one',
|
||||
orientations=[-1, 1, 0, 1, 1, 1, -1, -1, 0])
|
||||
sankey.add(flows=[-0.25, 0.15, 0.1], label='two',
|
||||
orientations=[-1, -1, -1], prior=0, connect=(0, 0))
|
||||
diagrams = sankey.finish()
|
||||
diagrams[-1].patch.set_hatch('/')
|
||||
plt.legend()
|
||||
```
|
||||
|
||||

|
||||
|
||||
请注意,只指定了一个连接,但系统形成一个电路,因为:(1)路径的长度是合理的,(2)流的方向和顺序是镜像的。
|
||||
|
||||
```python
|
||||
plt.show()
|
||||
```
|
||||
|
||||
## 参考
|
||||
|
||||
此示例中显示了以下函数,方法,类和模块的使用:
|
||||
|
||||
```python
|
||||
import matplotlib
|
||||
matplotlib.sankey
|
||||
matplotlib.sankey.Sankey
|
||||
matplotlib.sankey.Sankey.add
|
||||
matplotlib.sankey.Sankey.finish
|
||||
```
|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载python源码: sankey_basics.py](https://matplotlib.org/_downloads/sankey_basics.py)
|
||||
- [下载Jupyter notebook: sankey_basics.ipynb](https://matplotlib.org/_downloads/sankey_basics.ipynb)
|
||||
73
Python/matplotlab/gallery/specialty_plots/sankey_links.md
Normal file
73
Python/matplotlab/gallery/specialty_plots/sankey_links.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# 使用Sankey的长链连接
|
||||
|
||||
通过建立长链连接来演示/测试Sankey类。
|
||||
|
||||
```python
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.sankey import Sankey
|
||||
|
||||
links_per_side = 6
|
||||
|
||||
|
||||
def side(sankey, n=1):
|
||||
"""Generate a side chain."""
|
||||
prior = len(sankey.diagrams)
|
||||
for i in range(0, 2*n, 2):
|
||||
sankey.add(flows=[1, -1], orientations=[-1, -1],
|
||||
patchlabel=str(prior + i),
|
||||
prior=prior + i - 1, connect=(1, 0), alpha=0.5)
|
||||
sankey.add(flows=[1, -1], orientations=[1, 1],
|
||||
patchlabel=str(prior + i + 1),
|
||||
prior=prior + i, connect=(1, 0), alpha=0.5)
|
||||
|
||||
|
||||
def corner(sankey):
|
||||
"""Generate a corner link."""
|
||||
prior = len(sankey.diagrams)
|
||||
sankey.add(flows=[1, -1], orientations=[0, 1],
|
||||
patchlabel=str(prior), facecolor='k',
|
||||
prior=prior - 1, connect=(1, 0), alpha=0.5)
|
||||
|
||||
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(1, 1, 1, xticks=[], yticks=[],
|
||||
title="Why would you want to do this?\n(But you could.)")
|
||||
sankey = Sankey(ax=ax, unit=None)
|
||||
sankey.add(flows=[1, -1], orientations=[0, 1],
|
||||
patchlabel="0", facecolor='k',
|
||||
rotation=45)
|
||||
side(sankey, n=links_per_side)
|
||||
corner(sankey)
|
||||
side(sankey, n=links_per_side)
|
||||
corner(sankey)
|
||||
side(sankey, n=links_per_side)
|
||||
corner(sankey)
|
||||
side(sankey, n=links_per_side)
|
||||
sankey.finish()
|
||||
# Notice:
|
||||
# 1. The alignment doesn't drift significantly (if at all; with 16007
|
||||
# subdiagrams there is still closure).
|
||||
# 2. The first diagram is rotated 45 deg, so all other diagrams are rotated
|
||||
# accordingly.
|
||||
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 参考
|
||||
|
||||
此示例中显示了以下函数,方法,类和模块的使用:
|
||||
|
||||
```python
|
||||
import matplotlib
|
||||
matplotlib.sankey
|
||||
matplotlib.sankey.Sankey
|
||||
matplotlib.sankey.Sankey.add
|
||||
matplotlib.sankey.Sankey.finish
|
||||
```
|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载python源码: sankey_links.py](https://matplotlib.org/_downloads/sankey_links.py)
|
||||
- [下载Jupyter notebook: sankey_links.ipynb](https://matplotlib.org/_downloads/sankey_links.ipynb)
|
||||
100
Python/matplotlab/gallery/specialty_plots/sankey_rankine.md
Normal file
100
Python/matplotlab/gallery/specialty_plots/sankey_rankine.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# 朗肯动力循环
|
||||
|
||||
通过朗肯动力循环的实际示例演示Sankey类。
|
||||
|
||||
```python
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from matplotlib.sankey import Sankey
|
||||
|
||||
fig = plt.figure(figsize=(8, 9))
|
||||
ax = fig.add_subplot(1, 1, 1, xticks=[], yticks=[],
|
||||
title="Rankine Power Cycle: Example 8.6 from Moran and "
|
||||
"Shapiro\n\x22Fundamentals of Engineering Thermodynamics "
|
||||
"\x22, 6th ed., 2008")
|
||||
Hdot = [260.431, 35.078, 180.794, 221.115, 22.700,
|
||||
142.361, 10.193, 10.210, 43.670, 44.312,
|
||||
68.631, 10.758, 10.758, 0.017, 0.642,
|
||||
232.121, 44.559, 100.613, 132.168] # MW
|
||||
sankey = Sankey(ax=ax, format='%.3G', unit=' MW', gap=0.5, scale=1.0/Hdot[0])
|
||||
sankey.add(patchlabel='\n\nPump 1', rotation=90, facecolor='#37c959',
|
||||
flows=[Hdot[13], Hdot[6], -Hdot[7]],
|
||||
labels=['Shaft power', '', None],
|
||||
pathlengths=[0.4, 0.883, 0.25],
|
||||
orientations=[1, -1, 0])
|
||||
sankey.add(patchlabel='\n\nOpen\nheater', facecolor='#37c959',
|
||||
flows=[Hdot[11], Hdot[7], Hdot[4], -Hdot[8]],
|
||||
labels=[None, '', None, None],
|
||||
pathlengths=[0.25, 0.25, 1.93, 0.25],
|
||||
orientations=[1, 0, -1, 0], prior=0, connect=(2, 1))
|
||||
sankey.add(patchlabel='\n\nPump 2', facecolor='#37c959',
|
||||
flows=[Hdot[14], Hdot[8], -Hdot[9]],
|
||||
labels=['Shaft power', '', None],
|
||||
pathlengths=[0.4, 0.25, 0.25],
|
||||
orientations=[1, 0, 0], prior=1, connect=(3, 1))
|
||||
sankey.add(patchlabel='Closed\nheater', trunklength=2.914, fc='#37c959',
|
||||
flows=[Hdot[9], Hdot[1], -Hdot[11], -Hdot[10]],
|
||||
pathlengths=[0.25, 1.543, 0.25, 0.25],
|
||||
labels=['', '', None, None],
|
||||
orientations=[0, -1, 1, -1], prior=2, connect=(2, 0))
|
||||
sankey.add(patchlabel='Trap', facecolor='#37c959', trunklength=5.102,
|
||||
flows=[Hdot[11], -Hdot[12]],
|
||||
labels=['\n', None],
|
||||
pathlengths=[1.0, 1.01],
|
||||
orientations=[1, 1], prior=3, connect=(2, 0))
|
||||
sankey.add(patchlabel='Steam\ngenerator', facecolor='#ff5555',
|
||||
flows=[Hdot[15], Hdot[10], Hdot[2], -Hdot[3], -Hdot[0]],
|
||||
labels=['Heat rate', '', '', None, None],
|
||||
pathlengths=0.25,
|
||||
orientations=[1, 0, -1, -1, -1], prior=3, connect=(3, 1))
|
||||
sankey.add(patchlabel='\n\n\nTurbine 1', facecolor='#37c959',
|
||||
flows=[Hdot[0], -Hdot[16], -Hdot[1], -Hdot[2]],
|
||||
labels=['', None, None, None],
|
||||
pathlengths=[0.25, 0.153, 1.543, 0.25],
|
||||
orientations=[0, 1, -1, -1], prior=5, connect=(4, 0))
|
||||
sankey.add(patchlabel='\n\n\nReheat', facecolor='#37c959',
|
||||
flows=[Hdot[2], -Hdot[2]],
|
||||
labels=[None, None],
|
||||
pathlengths=[0.725, 0.25],
|
||||
orientations=[-1, 0], prior=6, connect=(3, 0))
|
||||
sankey.add(patchlabel='Turbine 2', trunklength=3.212, facecolor='#37c959',
|
||||
flows=[Hdot[3], Hdot[16], -Hdot[5], -Hdot[4], -Hdot[17]],
|
||||
labels=[None, 'Shaft power', None, '', 'Shaft power'],
|
||||
pathlengths=[0.751, 0.15, 0.25, 1.93, 0.25],
|
||||
orientations=[0, -1, 0, -1, 1], prior=6, connect=(1, 1))
|
||||
sankey.add(patchlabel='Condenser', facecolor='#58b1fa', trunklength=1.764,
|
||||
flows=[Hdot[5], -Hdot[18], -Hdot[6]],
|
||||
labels=['', 'Heat rate', None],
|
||||
pathlengths=[0.45, 0.25, 0.883],
|
||||
orientations=[-1, 1, 0], prior=8, connect=(2, 0))
|
||||
diagrams = sankey.finish()
|
||||
for diagram in diagrams:
|
||||
diagram.text.set_fontweight('bold')
|
||||
diagram.text.set_fontsize('10')
|
||||
for text in diagram.texts:
|
||||
text.set_fontsize('10')
|
||||
# Notice that the explicit connections are handled automatically, but the
|
||||
# implicit ones currently are not. The lengths of the paths and the trunks
|
||||
# must be adjusted manually, and that is a bit tricky.
|
||||
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 参考
|
||||
|
||||
此示例中显示了以下函数,方法,类和模块的使用:
|
||||
|
||||
```python
|
||||
import matplotlib
|
||||
matplotlib.sankey
|
||||
matplotlib.sankey.Sankey
|
||||
matplotlib.sankey.Sankey.add
|
||||
matplotlib.sankey.Sankey.finish
|
||||
```
|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载python源码: sankey_rankine.py](https://matplotlib.org/_downloads/sankey_rankine.py)
|
||||
- [下载Jupyter notebook: sankey_rankine.ipynb](https://matplotlib.org/_downloads/sankey_rankine.ipynb)
|
||||
304
Python/matplotlab/gallery/specialty_plots/skewt.md
Normal file
304
Python/matplotlab/gallery/specialty_plots/skewt.md
Normal file
@@ -0,0 +1,304 @@
|
||||
# SkewT-logP图:使用变换和自定义投影
|
||||
|
||||
这可以作为matplotlib变换和自定义投影API的强化练习。 这个例子产生了一个所谓的SkewT-logP图,它是气象学中用于显示温度垂直剖面的常见图。 就matplotlib而言,复杂性来自于X轴和Y轴不正交。 这是通过在基本Axes变换中包含一个偏斜分量来处理的。 处理上下X轴具有不同数据范围的事实带来了额外的复杂性,这需要一系列用于刻度,棘轮和轴的自定义类来处理这一问题。
|
||||
|
||||
```python
|
||||
from matplotlib.axes import Axes
|
||||
import matplotlib.transforms as transforms
|
||||
import matplotlib.axis as maxis
|
||||
import matplotlib.spines as mspines
|
||||
from matplotlib.projections import register_projection
|
||||
|
||||
|
||||
# The sole purpose of this class is to look at the upper, lower, or total
|
||||
# interval as appropriate and see what parts of the tick to draw, if any.
|
||||
class SkewXTick(maxis.XTick):
|
||||
def update_position(self, loc):
|
||||
# This ensures that the new value of the location is set before
|
||||
# any other updates take place
|
||||
self._loc = loc
|
||||
super().update_position(loc)
|
||||
|
||||
def _has_default_loc(self):
|
||||
return self.get_loc() is None
|
||||
|
||||
def _need_lower(self):
|
||||
return (self._has_default_loc() or
|
||||
transforms.interval_contains(self.axes.lower_xlim,
|
||||
self.get_loc()))
|
||||
|
||||
def _need_upper(self):
|
||||
return (self._has_default_loc() or
|
||||
transforms.interval_contains(self.axes.upper_xlim,
|
||||
self.get_loc()))
|
||||
|
||||
@property
|
||||
def gridOn(self):
|
||||
return (self._gridOn and (self._has_default_loc() or
|
||||
transforms.interval_contains(self.get_view_interval(),
|
||||
self.get_loc())))
|
||||
|
||||
@gridOn.setter
|
||||
def gridOn(self, value):
|
||||
self._gridOn = value
|
||||
|
||||
@property
|
||||
def tick1On(self):
|
||||
return self._tick1On and self._need_lower()
|
||||
|
||||
@tick1On.setter
|
||||
def tick1On(self, value):
|
||||
self._tick1On = value
|
||||
|
||||
@property
|
||||
def label1On(self):
|
||||
return self._label1On and self._need_lower()
|
||||
|
||||
@label1On.setter
|
||||
def label1On(self, value):
|
||||
self._label1On = value
|
||||
|
||||
@property
|
||||
def tick2On(self):
|
||||
return self._tick2On and self._need_upper()
|
||||
|
||||
@tick2On.setter
|
||||
def tick2On(self, value):
|
||||
self._tick2On = value
|
||||
|
||||
@property
|
||||
def label2On(self):
|
||||
return self._label2On and self._need_upper()
|
||||
|
||||
@label2On.setter
|
||||
def label2On(self, value):
|
||||
self._label2On = value
|
||||
|
||||
def get_view_interval(self):
|
||||
return self.axes.xaxis.get_view_interval()
|
||||
|
||||
|
||||
# This class exists to provide two separate sets of intervals to the tick,
|
||||
# as well as create instances of the custom tick
|
||||
class SkewXAxis(maxis.XAxis):
|
||||
def _get_tick(self, major):
|
||||
return SkewXTick(self.axes, None, '', major=major)
|
||||
|
||||
def get_view_interval(self):
|
||||
return self.axes.upper_xlim[0], self.axes.lower_xlim[1]
|
||||
|
||||
|
||||
# This class exists to calculate the separate data range of the
|
||||
# upper X-axis and draw the spine there. It also provides this range
|
||||
# to the X-axis artist for ticking and gridlines
|
||||
class SkewSpine(mspines.Spine):
|
||||
def _adjust_location(self):
|
||||
pts = self._path.vertices
|
||||
if self.spine_type == 'top':
|
||||
pts[:, 0] = self.axes.upper_xlim
|
||||
else:
|
||||
pts[:, 0] = self.axes.lower_xlim
|
||||
|
||||
|
||||
# This class handles registration of the skew-xaxes as a projection as well
|
||||
# as setting up the appropriate transformations. It also overrides standard
|
||||
# spines and axes instances as appropriate.
|
||||
class SkewXAxes(Axes):
|
||||
# The projection must specify a name. This will be used be the
|
||||
# user to select the projection, i.e. ``subplot(111,
|
||||
# projection='skewx')``.
|
||||
name = 'skewx'
|
||||
|
||||
def _init_axis(self):
|
||||
# Taken from Axes and modified to use our modified X-axis
|
||||
self.xaxis = SkewXAxis(self)
|
||||
self.spines['top'].register_axis(self.xaxis)
|
||||
self.spines['bottom'].register_axis(self.xaxis)
|
||||
self.yaxis = maxis.YAxis(self)
|
||||
self.spines['left'].register_axis(self.yaxis)
|
||||
self.spines['right'].register_axis(self.yaxis)
|
||||
|
||||
def _gen_axes_spines(self):
|
||||
spines = {'top': SkewSpine.linear_spine(self, 'top'),
|
||||
'bottom': mspines.Spine.linear_spine(self, 'bottom'),
|
||||
'left': mspines.Spine.linear_spine(self, 'left'),
|
||||
'right': mspines.Spine.linear_spine(self, 'right')}
|
||||
return spines
|
||||
|
||||
def _set_lim_and_transforms(self):
|
||||
"""
|
||||
This is called once when the plot is created to set up all the
|
||||
transforms for the data, text and grids.
|
||||
"""
|
||||
rot = 30
|
||||
|
||||
# Get the standard transform setup from the Axes base class
|
||||
Axes._set_lim_and_transforms(self)
|
||||
|
||||
# Need to put the skew in the middle, after the scale and limits,
|
||||
# but before the transAxes. This way, the skew is done in Axes
|
||||
# coordinates thus performing the transform around the proper origin
|
||||
# We keep the pre-transAxes transform around for other users, like the
|
||||
# spines for finding bounds
|
||||
self.transDataToAxes = self.transScale + \
|
||||
self.transLimits + transforms.Affine2D().skew_deg(rot, 0)
|
||||
|
||||
# Create the full transform from Data to Pixels
|
||||
self.transData = self.transDataToAxes + self.transAxes
|
||||
|
||||
# Blended transforms like this need to have the skewing applied using
|
||||
# both axes, in axes coords like before.
|
||||
self._xaxis_transform = (transforms.blended_transform_factory(
|
||||
self.transScale + self.transLimits,
|
||||
transforms.IdentityTransform()) +
|
||||
transforms.Affine2D().skew_deg(rot, 0)) + self.transAxes
|
||||
|
||||
@property
|
||||
def lower_xlim(self):
|
||||
return self.axes.viewLim.intervalx
|
||||
|
||||
@property
|
||||
def upper_xlim(self):
|
||||
pts = [[0., 1.], [1., 1.]]
|
||||
return self.transDataToAxes.inverted().transform(pts)[:, 0]
|
||||
|
||||
|
||||
# Now register the projection with matplotlib so the user can select
|
||||
# it.
|
||||
register_projection(SkewXAxes)
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Now make a simple example using the custom projection.
|
||||
from io import StringIO
|
||||
from matplotlib.ticker import (MultipleLocator, NullFormatter,
|
||||
ScalarFormatter)
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
# Some examples data
|
||||
data_txt = '''
|
||||
978.0 345 7.8 0.8 61 4.16 325 14 282.7 294.6 283.4
|
||||
971.0 404 7.2 0.2 61 4.01 327 17 282.7 294.2 283.4
|
||||
946.7 610 5.2 -1.8 61 3.56 335 26 282.8 293.0 283.4
|
||||
944.0 634 5.0 -2.0 61 3.51 336 27 282.8 292.9 283.4
|
||||
925.0 798 3.4 -2.6 65 3.43 340 32 282.8 292.7 283.4
|
||||
911.8 914 2.4 -2.7 69 3.46 345 37 282.9 292.9 283.5
|
||||
906.0 966 2.0 -2.7 71 3.47 348 39 283.0 293.0 283.6
|
||||
877.9 1219 0.4 -3.2 77 3.46 0 48 283.9 293.9 284.5
|
||||
850.0 1478 -1.3 -3.7 84 3.44 0 47 284.8 294.8 285.4
|
||||
841.0 1563 -1.9 -3.8 87 3.45 358 45 285.0 295.0 285.6
|
||||
823.0 1736 1.4 -0.7 86 4.44 353 42 290.3 303.3 291.0
|
||||
813.6 1829 4.5 1.2 80 5.17 350 40 294.5 309.8 295.4
|
||||
809.0 1875 6.0 2.2 77 5.57 347 39 296.6 313.2 297.6
|
||||
798.0 1988 7.4 -0.6 57 4.61 340 35 299.2 313.3 300.1
|
||||
791.0 2061 7.6 -1.4 53 4.39 335 33 300.2 313.6 301.0
|
||||
783.9 2134 7.0 -1.7 54 4.32 330 31 300.4 313.6 301.2
|
||||
755.1 2438 4.8 -3.1 57 4.06 300 24 301.2 313.7 301.9
|
||||
727.3 2743 2.5 -4.4 60 3.81 285 29 301.9 313.8 302.6
|
||||
700.5 3048 0.2 -5.8 64 3.57 275 31 302.7 313.8 303.3
|
||||
700.0 3054 0.2 -5.8 64 3.56 280 31 302.7 313.8 303.3
|
||||
698.0 3077 0.0 -6.0 64 3.52 280 31 302.7 313.7 303.4
|
||||
687.0 3204 -0.1 -7.1 59 3.28 281 31 304.0 314.3 304.6
|
||||
648.9 3658 -3.2 -10.9 55 2.59 285 30 305.5 313.8 305.9
|
||||
631.0 3881 -4.7 -12.7 54 2.29 289 33 306.2 313.6 306.6
|
||||
600.7 4267 -6.4 -16.7 44 1.73 295 39 308.6 314.3 308.9
|
||||
592.0 4381 -6.9 -17.9 41 1.59 297 41 309.3 314.6 309.6
|
||||
577.6 4572 -8.1 -19.6 39 1.41 300 44 310.1 314.9 310.3
|
||||
555.3 4877 -10.0 -22.3 36 1.16 295 39 311.3 315.3 311.5
|
||||
536.0 5151 -11.7 -24.7 33 0.97 304 39 312.4 315.8 312.6
|
||||
533.8 5182 -11.9 -25.0 33 0.95 305 39 312.5 315.8 312.7
|
||||
500.0 5680 -15.9 -29.9 29 0.64 290 44 313.6 315.9 313.7
|
||||
472.3 6096 -19.7 -33.4 28 0.49 285 46 314.1 315.8 314.1
|
||||
453.0 6401 -22.4 -36.0 28 0.39 300 50 314.4 315.8 314.4
|
||||
400.0 7310 -30.7 -43.7 27 0.20 285 44 315.0 315.8 315.0
|
||||
399.7 7315 -30.8 -43.8 27 0.20 285 44 315.0 315.8 315.0
|
||||
387.0 7543 -33.1 -46.1 26 0.16 281 47 314.9 315.5 314.9
|
||||
382.7 7620 -33.8 -46.8 26 0.15 280 48 315.0 315.6 315.0
|
||||
342.0 8398 -40.5 -53.5 23 0.08 293 52 316.1 316.4 316.1
|
||||
320.4 8839 -43.7 -56.7 22 0.06 300 54 317.6 317.8 317.6
|
||||
318.0 8890 -44.1 -57.1 22 0.05 301 55 317.8 318.0 317.8
|
||||
310.0 9060 -44.7 -58.7 19 0.04 304 61 319.2 319.4 319.2
|
||||
306.1 9144 -43.9 -57.9 20 0.05 305 63 321.5 321.7 321.5
|
||||
305.0 9169 -43.7 -57.7 20 0.05 303 63 322.1 322.4 322.1
|
||||
300.0 9280 -43.5 -57.5 20 0.05 295 64 323.9 324.2 323.9
|
||||
292.0 9462 -43.7 -58.7 17 0.05 293 67 326.2 326.4 326.2
|
||||
276.0 9838 -47.1 -62.1 16 0.03 290 74 326.6 326.7 326.6
|
||||
264.0 10132 -47.5 -62.5 16 0.03 288 79 330.1 330.3 330.1
|
||||
251.0 10464 -49.7 -64.7 16 0.03 285 85 331.7 331.8 331.7
|
||||
250.0 10490 -49.7 -64.7 16 0.03 285 85 332.1 332.2 332.1
|
||||
247.0 10569 -48.7 -63.7 16 0.03 283 88 334.7 334.8 334.7
|
||||
244.0 10649 -48.9 -63.9 16 0.03 280 91 335.6 335.7 335.6
|
||||
243.3 10668 -48.9 -63.9 16 0.03 280 91 335.8 335.9 335.8
|
||||
220.0 11327 -50.3 -65.3 15 0.03 280 85 343.5 343.6 343.5
|
||||
212.0 11569 -50.5 -65.5 15 0.03 280 83 346.8 346.9 346.8
|
||||
210.0 11631 -49.7 -64.7 16 0.03 280 83 349.0 349.1 349.0
|
||||
200.0 11950 -49.9 -64.9 15 0.03 280 80 353.6 353.7 353.6
|
||||
194.0 12149 -49.9 -64.9 15 0.03 279 78 356.7 356.8 356.7
|
||||
183.0 12529 -51.3 -66.3 15 0.03 278 75 360.4 360.5 360.4
|
||||
164.0 13233 -55.3 -68.3 18 0.02 277 69 365.2 365.3 365.2
|
||||
152.0 13716 -56.5 -69.5 18 0.02 275 65 371.1 371.2 371.1
|
||||
150.0 13800 -57.1 -70.1 18 0.02 275 64 371.5 371.6 371.5
|
||||
136.0 14414 -60.5 -72.5 19 0.02 268 54 376.0 376.1 376.0
|
||||
132.0 14600 -60.1 -72.1 19 0.02 265 51 380.0 380.1 380.0
|
||||
131.4 14630 -60.2 -72.2 19 0.02 265 51 380.3 380.4 380.3
|
||||
128.0 14792 -60.9 -72.9 19 0.02 266 50 381.9 382.0 381.9
|
||||
125.0 14939 -60.1 -72.1 19 0.02 268 49 385.9 386.0 385.9
|
||||
119.0 15240 -62.2 -73.8 20 0.01 270 48 387.4 387.5 387.4
|
||||
112.0 15616 -64.9 -75.9 21 0.01 265 53 389.3 389.3 389.3
|
||||
108.0 15838 -64.1 -75.1 21 0.01 265 58 394.8 394.9 394.8
|
||||
107.8 15850 -64.1 -75.1 21 0.01 265 58 395.0 395.1 395.0
|
||||
105.0 16010 -64.7 -75.7 21 0.01 272 50 396.9 396.9 396.9
|
||||
103.0 16128 -62.9 -73.9 21 0.02 277 45 402.5 402.6 402.5
|
||||
100.0 16310 -62.5 -73.5 21 0.02 285 36 406.7 406.8 406.7
|
||||
'''
|
||||
|
||||
# Parse the data
|
||||
sound_data = StringIO(data_txt)
|
||||
p, h, T, Td = np.loadtxt(sound_data, usecols=range(0, 4), unpack=True)
|
||||
|
||||
# Create a new figure. The dimensions here give a good aspect ratio
|
||||
fig = plt.figure(figsize=(6.5875, 6.2125))
|
||||
ax = fig.add_subplot(111, projection='skewx')
|
||||
|
||||
plt.grid(True)
|
||||
|
||||
# Plot the data using normal plotting functions, in this case using
|
||||
# log scaling in Y, as dictated by the typical meteorological plot
|
||||
ax.semilogy(T, p, color='C3')
|
||||
ax.semilogy(Td, p, color='C2')
|
||||
|
||||
# An example of a slanted line at constant X
|
||||
l = ax.axvline(0, color='C0')
|
||||
|
||||
# Disables the log-formatting that comes with semilogy
|
||||
ax.yaxis.set_major_formatter(ScalarFormatter())
|
||||
ax.yaxis.set_minor_formatter(NullFormatter())
|
||||
ax.set_yticks(np.linspace(100, 1000, 10))
|
||||
ax.set_ylim(1050, 100)
|
||||
|
||||
ax.xaxis.set_major_locator(MultipleLocator(10))
|
||||
ax.set_xlim(-50, 50)
|
||||
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 参考
|
||||
|
||||
此示例中显示了以下函数,方法,类和模块的使用:
|
||||
|
||||
```python
|
||||
import matplotlib
|
||||
matplotlib.transforms
|
||||
matplotlib.spines
|
||||
matplotlib.spines.Spine
|
||||
matplotlib.spines.Spine.register_axis
|
||||
matplotlib.projections
|
||||
matplotlib.projections.register_projection
|
||||
```
|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载python源码: skewt.py](https://matplotlib.org/_downloads/skewt.py)
|
||||
- [下载Jupyter notebook: skewt.ipynb](https://matplotlib.org/_downloads/skewt.ipynb)
|
||||
84
Python/matplotlab/gallery/specialty_plots/system_monitor.md
Normal file
84
Python/matplotlab/gallery/specialty_plots/system_monitor.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# 系统监视器
|
||||
|
||||

|
||||
|
||||
输出:
|
||||
|
||||
```python
|
||||
75.0 frames per second
|
||||
```
|
||||
|
||||
```python
|
||||
import time
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
|
||||
def get_memory(t):
|
||||
"Simulate a function that returns system memory"
|
||||
return 100 * (0.5 + 0.5 * np.sin(0.5 * np.pi * t))
|
||||
|
||||
|
||||
def get_cpu(t):
|
||||
"Simulate a function that returns cpu usage"
|
||||
return 100 * (0.5 + 0.5 * np.sin(0.2 * np.pi * (t - 0.25)))
|
||||
|
||||
|
||||
def get_net(t):
|
||||
"Simulate a function that returns network bandwidth"
|
||||
return 100 * (0.5 + 0.5 * np.sin(0.7 * np.pi * (t - 0.1)))
|
||||
|
||||
|
||||
def get_stats(t):
|
||||
return get_memory(t), get_cpu(t), get_net(t)
|
||||
|
||||
fig, ax = plt.subplots()
|
||||
ind = np.arange(1, 4)
|
||||
|
||||
# show the figure, but do not block
|
||||
plt.show(block=False)
|
||||
|
||||
|
||||
pm, pc, pn = plt.bar(ind, get_stats(0))
|
||||
pm.set_facecolor('r')
|
||||
pc.set_facecolor('g')
|
||||
pn.set_facecolor('b')
|
||||
ax.set_xticks(ind)
|
||||
ax.set_xticklabels(['Memory', 'CPU', 'Bandwidth'])
|
||||
ax.set_ylim([0, 100])
|
||||
ax.set_ylabel('Percent usage')
|
||||
ax.set_title('System Monitor')
|
||||
|
||||
start = time.time()
|
||||
for i in range(200): # run for a little while
|
||||
m, c, n = get_stats(i / 10.0)
|
||||
|
||||
# update the animated artists
|
||||
pm.set_height(m)
|
||||
pc.set_height(c)
|
||||
pn.set_height(n)
|
||||
|
||||
# ask the canvas to re-draw itself the next time it
|
||||
# has a chance.
|
||||
# For most of the GUI backends this adds an event to the queue
|
||||
# of the GUI frameworks event loop.
|
||||
fig.canvas.draw_idle()
|
||||
try:
|
||||
# make sure that the GUI framework has a chance to run its event loop
|
||||
# and clear any GUI events. This needs to be in a try/except block
|
||||
# because the default implementation of this method is to raise
|
||||
# NotImplementedError
|
||||
fig.canvas.flush_events()
|
||||
except NotImplementedError:
|
||||
pass
|
||||
|
||||
stop = time.time()
|
||||
print("{fps:.1f} frames per second".format(fps=200 / (stop - start)))
|
||||
```
|
||||
|
||||
脚本的总运行时间:(0分钟2.678秒)
|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载python源码: system_monitor.py](https://matplotlib.org/_downloads/system_monitor.py)
|
||||
- [下载Jupyter notebook: system_monitor.ipynb](https://matplotlib.org/_downloads/system_monitor.ipynb)
|
||||
@@ -0,0 +1,75 @@
|
||||
# 地形山体阴影
|
||||
|
||||
在“山体阴影”图上展示不同混合模式和垂直夸大的视觉效果。
|
||||
|
||||
请注意,“叠加”和“柔和”混合模式适用于复杂曲面,例如此示例,而默认的“hsv”混合模式最适用于光滑曲面,例如许多数学函数。
|
||||
|
||||
在大多数情况下,山体阴影纯粹用于视觉目的,可以安全地忽略dx / dy。 在这种情况下,您可以通过反复试验调整vert_exag(垂直夸大)以获得所需的视觉效果。 但是,此示例演示了如何使用dx和dy kwargs来确保vert_exag参数是真正的垂直夸大。
|
||||
|
||||

|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.cbook import get_sample_data
|
||||
from matplotlib.colors import LightSource
|
||||
|
||||
|
||||
with np.load(get_sample_data('jacksboro_fault_dem.npz')) as dem:
|
||||
z = dem['elevation']
|
||||
|
||||
#-- Optional dx and dy for accurate vertical exaggeration ----------------
|
||||
# If you need topographically accurate vertical exaggeration, or you don't
|
||||
# want to guess at what *vert_exag* should be, you'll need to specify the
|
||||
# cellsize of the grid (i.e. the *dx* and *dy* parameters). Otherwise, any
|
||||
# *vert_exag* value you specify will be relative to the grid spacing of
|
||||
# your input data (in other words, *dx* and *dy* default to 1.0, and
|
||||
# *vert_exag* is calculated relative to those parameters). Similarly, *dx*
|
||||
# and *dy* are assumed to be in the same units as your input z-values.
|
||||
# Therefore, we'll need to convert the given dx and dy from decimal degrees
|
||||
# to meters.
|
||||
dx, dy = dem['dx'], dem['dy']
|
||||
dy = 111200 * dy
|
||||
dx = 111200 * dx * np.cos(np.radians(dem['ymin']))
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
# Shade from the northwest, with the sun 45 degrees from horizontal
|
||||
ls = LightSource(azdeg=315, altdeg=45)
|
||||
cmap = plt.cm.gist_earth
|
||||
|
||||
fig, axes = plt.subplots(nrows=4, ncols=3, figsize=(8, 9))
|
||||
plt.setp(axes.flat, xticks=[], yticks=[])
|
||||
|
||||
# Vary vertical exaggeration and blend mode and plot all combinations
|
||||
for col, ve in zip(axes.T, [0.1, 1, 10]):
|
||||
# Show the hillshade intensity image in the first row
|
||||
col[0].imshow(ls.hillshade(z, vert_exag=ve, dx=dx, dy=dy), cmap='gray')
|
||||
|
||||
# Place hillshaded plots with different blend modes in the rest of the rows
|
||||
for ax, mode in zip(col[1:], ['hsv', 'overlay', 'soft']):
|
||||
rgb = ls.shade(z, cmap=cmap, blend_mode=mode,
|
||||
vert_exag=ve, dx=dx, dy=dy)
|
||||
ax.imshow(rgb)
|
||||
|
||||
# Label rows and columns
|
||||
for ax, ve in zip(axes[0], [0.1, 1, 10]):
|
||||
ax.set_title('{0}'.format(ve), size=18)
|
||||
for ax, mode in zip(axes[:, 0], ['Hillshade', 'hsv', 'overlay', 'soft']):
|
||||
ax.set_ylabel(mode, size=18)
|
||||
|
||||
# Group labels...
|
||||
axes[0, 1].annotate('Vertical Exaggeration', (0.5, 1), xytext=(0, 30),
|
||||
textcoords='offset points', xycoords='axes fraction',
|
||||
ha='center', va='bottom', size=20)
|
||||
axes[2, 0].annotate('Blend Mode', (0, 0.5), xytext=(-30, 0),
|
||||
textcoords='offset points', xycoords='axes fraction',
|
||||
ha='right', va='center', size=20, rotation=90)
|
||||
fig.subplots_adjust(bottom=0.05, right=0.95)
|
||||
|
||||
plt.show()
|
||||
```
|
||||
|
||||
## 下载这个示例
|
||||
|
||||
- [下载python源码: topographic_hillshading.py](https://matplotlib.org/_downloads/topographic_hillshading.py)
|
||||
- [下载Jupyter notebook: topographic_hillshading.ipynb](https://matplotlib.org/_downloads/topographic_hillshading.ipynb)
|
||||
Reference in New Issue
Block a user