Matplotlib教程

Matplotlib教程

1、介绍

matplotlib可能是2D图形最常用的Python软件包。它提供了一种非常快速的方式来可视化来自Python的数据以及多种格式的具有出版物质量的图形。我们将以交互模式探索matplotlib,涵盖最常见的情况。

IPython和pylab模式

IPython

IPython 是增强的交互式Python Shell,具有许多有趣的功能,包括命名的输入和输出,对Shell命令的访问,改进的调试等。当我们使用命令行参数-pylab(从IPython版本0.12开始为–pylab)启动它时,它允许具有类似Matlab / Mathematica功能的交互式matplotlib会话。

pyplot

pyplot为matplotlib面向对象的绘图库提供了方便的接口。它是根据Matlab ™紧密建模的。因此,大多数在pyplot中的绘图命令都具有带有类似参数的Matlab™类似物。重要命令将通过交互式示例进行说明。

2、简单绘图

在本节中,我们要在同一图上绘制余弦和正弦函数。从默认设置开始,我们将逐步丰富该数字以使其更美观。

第一步是获取正弦和余弦函数的数据:

import numpy as np

X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
C, S = np.cos(X), np.sin(X)

X现在是一个NumPy数组,具有256个值,范围从-π到+π(包括)。 C是余弦(256个值),S是正弦(256个值)。要运行示例,可以使用以下命令运行它:

$ python exercice_1.py

使用默认值

文献资料

在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt

X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
C,S = np.cos(X), np.sin(X)

plt.plot(X,C)
plt.plot(X,S)

plt.show()

Matplotlib带有一组默认设置,这些设置允许自定义各种属性。您可以控制matplotlib几乎每个属性的默认值:图形大小和dpi,线宽,颜色和样式,轴,轴和网格属性,文本和字体属性等等。尽管在大多数情况下,matplotlib的默认值相当不错,但您可能需要针对特定​​情况修改某些属性。

实例化默认值

在这里插入图片描述

# Imports
import numpy as np
import matplotlib.pyplot as plt

# Create a new figure of size 8x6 points, using 100 dots per inch
plt.figure(figsize=(8,6), dpi=100)

# Create a new subplot from a grid of 1x1
plt.subplot(111)

X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)

# Plot cosine using blue color with a continuous line of width 1 (pixels)
plt.plot(X, C, color="blue", linewidth=1.0, linestyle="-")

# Plot sine using green color with a continuous line of width 1 (pixels)
plt.plot(X, S, color="green", linewidth=1.0, linestyle="-")

# Set x limits
plt.xlim(-4.0,4.0)

# Set x ticks
plt.xticks(np.linspace(-4,4,9,endpoint=True))

# Set y limits
plt.ylim(-1.0,1.0)

# Set y ticks
plt.yticks(np.linspace(-1,1,5,endpoint=True))

# Save figure using 72 dots per inch
# savefig("../figures/exercice_2.png",dpi=72)

# Show result on screen
plt.show()

在下面的脚本中,我们实例化(并注释了)所有会影响图形外观的图形设置。这些设置已明确设置为默认值,但是现在您可以交互地使用这些值来探索其影响(请参见下面的“线属性” 和“线样式” )。

更改颜色和线宽

文献资料

在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt

plt.figure(figsize=(8,5), dpi=80)
plt.subplot(111)

X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)

plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-")

plt.xlim(-4.0,4.0)
plt.xticks(np.linspace(-4,4,9,endpoint=True))

plt.ylim(-1.0,1.0)
plt.yticks(np.linspace(-1,1,5,endpoint=True))

plt.show()

第一步,我们要使余弦为蓝色,正弦为红色,并且将两者都稍粗一些。我们还将略微改变数字大小以使其更水平。

   ...
   plt.figure(figsize=(10,6), dpi=80)
   plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-")
   plt.plot(X, S, color="red",  linewidth=2.5, linestyle="-")
   ...

设定limits

文献资料

在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt


plt.figure(figsize=(8,5), dpi=80)
plt.subplot(111)

X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)

plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-")

plt.xlim(X.min()*1.1, X.max()*1.1)
plt.ylim(C.min()*1.1,C.max()*1.1)

plt.show()

该图的当前限制有点太紧,我们要留一些空间以便清楚地看到所有数据点。

   ...
   plt.xlim(X.min()*1.1, X.max()*1.1)
   plt.ylim(C.min()*1.1, C.max()*1.1)
   ...

设置刻度

文献资料

在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt

plt.figure(figsize=(8,5), dpi=80)
plt.subplot(111)

X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)

plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-")

plt.xlim(X.min()*1.1, X.max()*1.1)
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi])

plt.ylim(C.min()*1.1,C.max()*1.1)
plt.yticks([-1, 0, +1])

plt.show()

当前刻度不是理想的,对其进行更改,使其仅显示值 (+/-π,+/-π/2)。

   ...
   plt.xticks( [-np.pi, -np.pi/2, 0, np.pi/2, np.pi])
   plt.yticks([-1, 0, +1])
   ...

设置刻度标签

文献资料

在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt

plt.figure(figsize=(8,5), dpi=80)
plt.subplot(111)

X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)

plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-")

plt.xlim(X.min()*1.1, X.max()*1.1)
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
       [r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])

plt.ylim(C.min()*1.1,C.max()*1.1)
plt.yticks([-1, 0, +1],
       [r'$-1$', r'$0$', r'$+1$'])

plt.show()

刻度现在已正确放置,但其标签不是很明确。我们可以猜测3.142是π,但最好使其明确。当设置值时,我们还可以在第二个参数列表中提供相应的标签。请注意,我们将使用latex来更好地呈现标签。

   ...
   plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
          [r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])

   plt.yticks([-1, 0, +1],
          [r'$-1$', r'$0$', r'$+1$'])
   ...

移动脊线

文献资料

在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt

plt.figure(figsize=(8,5), dpi=80)
ax = plt.subplot(111)

ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))

X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)

plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-")


plt.xlim(X.min()*1.1, X.max()*1.1)
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
       [r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])

plt.ylim(C.min()*1.1,C.max()*1.1)
plt.yticks([-1, 0, +1],
       [r'$-1$', r'$0$', r'$+1$'])

plt.show()

脊线是连接轴刻度线并注意数据区域边界的线。可以将它们放置在任意位置,直到现在,它们都位于轴的边界上。因为我们希望将它们放在中间,所以我们将对其进行更改。由于它们有四个(顶部/底部/左侧/右侧),因此我们将顶部和右侧的颜色设置为none来丢弃顶部和右侧,并将底部和左侧的颜色移动到数据空间坐标中的坐标0。

   ...
   ax = plt.gca()
   ax.spines['right'].set_color('none')
   ax.spines['top'].set_color('none')
   ax.xaxis.set_ticks_position('bottom')
   ax.spines['bottom'].set_position(('data',0))
   ax.yaxis.set_ticks_position('left')
   ax.spines['left'].set_position(('data',0))
   ...

添加图例

文献资料

在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt

plt.figure(figsize=(8,5), dpi=80)
ax = plt.subplot(111)
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))

X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)

plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-", label="cosine")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-", label="sine")

plt.xlim(X.min()*1.1, X.max()*1.1)
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
           [r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])

plt.ylim(C.min()*1.1,C.max()*1.1)
plt.yticks([-1, +1],
           [r'$-1$', r'$+1$'])

plt.legend(loc='upper left', frameon=False)
# plt.savefig("../figures/exercice_8.png",dpi=72)
plt.show()

在左上角添加一个图例。这仅需要将关键字参数标签(将在图例框中使用)添加到plot命令。

   ...
   plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-", label="cosine")
   plt.plot(X, S, color="red",  linewidth=2.5, linestyle="-", label="sine")

   plt.legend(loc='upper left', frameon=False)
   ...

注释

文献资料

在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt

plt.figure(figsize=(8,5), dpi=80)
ax = plt.subplot(111)
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))

X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)

plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-", label="cosine")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-",  label="sine")

plt.xlim(X.min()*1.1, X.max()*1.1)
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
           [r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])

plt.ylim(C.min()*1.1,C.max()*1.1)
plt.yticks([-1, +1],
           [r'$-1$', r'$+1$'])

t = 2*np.pi/3
plt.plot([t,t],[0,np.cos(t)],
         color ='blue',  linewidth=1.5, linestyle="--")
plt.scatter([t,],[np.cos(t),], 50, color ='blue')
plt.annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$',
             xy=(t, np.cos(t)),  xycoords='data',
             xytext=(-90, -50), textcoords='offset points', fontsize=16,
             arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))

plt.plot([t,t],[0,np.sin(t)],
         color ='red',  linewidth=1.5, linestyle="--")
plt.scatter([t,],[np.sin(t),], 50, color ='red')
plt.annotate(r'$\sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$',
             xy=(t, np.sin(t)),  xycoords='data',
             xytext=(+10, +30), textcoords='offset points', fontsize=16,
             arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))

plt.legend(loc='upper left', frameon=False)
plt.savefig("../figures/exercice_9.png",dpi=72)
plt.show()

使用anateate命令来注释一些要点。我们选择 2 π / 3 2\pi / 3 2π/3值,并且要同时注释正弦和余弦。我们将首先在曲线上绘制标记以及一条直线。然后,我们将使用annotate命令显示一些带有箭头的文本。

   ...
   t = 2*np.pi/3
   plt.plot([t,t],[0,np.cos(t)], color ='blue', linewidth=1.5, linestyle="--")
   plt.scatter([t,],[np.cos(t),], 50, color ='blue')

   plt.annotate(r'$\sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$',
                xy=(t, np.sin(t)), xycoords='data',
                xytext=(+10, +30), textcoords='offset points', fontsize=16,
                arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))

   plt.plot([t,t],[0,np.sin(t)], color ='red', linewidth=1.5, linestyle="--")
   plt.scatter([t,],[np.sin(t),], 50, color ='red')

   plt.annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$',
                xy=(t, np.cos(t)), xycoords='data',
                xytext=(-90, -50), textcoords='offset points', fontsize=16,
                arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
   ...

细节

文献资料

在这里插入图片描述

由于蓝线和红线,现在几乎看不到刻度线标签。我们可以使它们变大,也可以调整它们的属性,以使它们在半透明的白色背景上消失。这将使我们能够同时看到数据和标签。

   ...
   for label in ax.get_xticklabels() + ax.get_yticklabels():
       label.set_fontsize(16)
       label.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.65 ))
   ...

3、图形、子图、轴和记号

到目前为止,我们已经使用隐式图形和轴创建。这对于快速绘图很方便。我们可以显式地使用figure、subplot和axes对显示进行更多的控制。matplotlib中的图形表示用户界面中的整个窗口。在这个图中可以有子图。虽然子图将绘图放置在规则的网格中,但轴允许在图形中自由放置。我们已经使用了figures和subplot,但没有显式地调用它们。调用plot时,matplotlib调用gca()获取当前轴,gca依次调用gcf()获取当前图形。如果没有,它调用figure()来生成一个,严格地说是peaking,生成一个subplot(111)。让我们看看细节。

图形

图形是GUI中带有“图形#”作为标题的窗口。数字从1开始编号,而普通的Python从0开始编号。这显然是MATLAB风格的。有几个参数可以确定图形的外观:

ArgumentDefaultDescription
num1图形数
figsizefigure.figsize图形尺寸,以英寸为单位(width, height)
dpifigure.dpi分辨率(每英寸点数)
facecolorfigure.facecolor绘图背景的颜色
edgecolorfigure.edgecolor绘图背景边缘的颜色
frameonTrue是否画图框

可以在资源文件中指定默认值,并将在大多数时间使用。只有图形的编号经常更改。

使用GUI时,可以通过单击右上角的x来关闭图形。您还可以通过调用close以编程方式关闭图形。根据参数,它关闭(1)当前图形(无参数),(2)特定图形(数字或图形实例参数)或(3)所有图形(全部作为参数)。使用set_something方法设置图形属性。

子图

使用子图,您可以在常规网格中排列图。您需要指定行和列的数量以及图的数量。 请注意 gridspec命令是一个更强大的选择。

在这里插入图片描述

from pylab import *

subplot(2,1,1)
xticks([]), yticks([])
text(0.5,0.5, 'subplot(2,1,1)',ha='center',va='center',size=24,alpha=.5)

subplot(2,1,2)
xticks([]), yticks([])
text(0.5,0.5, 'subplot(2,1,2)',ha='center',va='center',size=24,alpha=.5)

# plt.savefig('../figures/subplot-horizontal.png', dpi=64)
show()

在这里插入图片描述

from pylab import *

subplot(1,2,1)
xticks([]), yticks([])
text(0.5,0.5, 'subplot(2,2,1)',ha='center',va='center',size=24,alpha=.5)

subplot(1,2,2)
xticks([]), yticks([])
text(0.5,0.5, 'subplot(2,2,2)',ha='center',va='center',size=24,alpha=.5)

# plt.savefig('../figures/subplot-vertical.png', dpi=64)
show()

在这里插入图片描述

from pylab import *

subplot(2,2,1)
xticks([]), yticks([])
text(0.5,0.5, 'subplot(2,2,1)',ha='center',va='center',size=20,alpha=.5)

subplot(2,2,2)
xticks([]), yticks([])
text(0.5,0.5, 'subplot(2,2,2)',ha='center',va='center',size=20,alpha=.5)

subplot(2,2,3)
xticks([]), yticks([])
text(0.5,0.5, 'subplot(2,2,3)',ha='center',va='center',size=20,alpha=.5)

subplot(2,2,4)
xticks([]), yticks([])
text(0.5,0.5, 'subplot(2,2,4)',ha='center',va='center',size=20,alpha=.5)

# savefig('../figures/subplot-grid.png', dpi=64)
show()

坐标轴

轴与子图非常相似,但允许在图中的任何位置放置图。所以,如果我们想把一个较小的图放在一个较大的图里面,我们就用坐标轴。

在这里插入图片描述

from pylab import *
import matplotlib.gridspec as gridspec

G = gridspec.GridSpec(3, 3)

axes_1 = subplot(G[0, :])
xticks([]), yticks([])
text(0.5,0.5, 'Axes 1',ha='center',va='center',size=24,alpha=.5)

axes_2 = subplot(G[1,:-1])
xticks([]), yticks([])
text(0.5,0.5, 'Axes 2',ha='center',va='center',size=24,alpha=.5)

axes_3 = subplot(G[1:, -1])
xticks([]), yticks([])
text(0.5,0.5, 'Axes 3',ha='center',va='center',size=24,alpha=.5)

axes_4 = subplot(G[-1,0])
xticks([]), yticks([])
text(0.5,0.5, 'Axes 4',ha='center',va='center',size=24,alpha=.5)

axes_5 = subplot(G[-1,-2])
xticks([]), yticks([])
text(0.5,0.5, 'Axes 5',ha='center',va='center',size=24,alpha=.5)

#plt.savefig('../figures/gridspec.png', dpi=64)
show()

在这里插入图片描述

import matplotlib.pyplot as plt

plt.axes([0.1,0.1,.8,.8])
plt.xticks([]), plt.yticks([])
plt.text(0.6,0.6, 'axes([0.1,0.1,.8,.8])',ha='center',va='center',size=20,alpha=.5)

plt.axes([0.2,0.2,.3,.3])
plt.xticks([]), plt.yticks([])
plt.text(0.5,0.5, 'axes([0.2,0.2,.3,.3])',ha='center',va='center',size=16,alpha=.5)

plt.savefig("../figures/axes.png",dpi=64)
plt.show()()

在这里插入图片描述

import matplotlib.pyplot as plt

plt.axes([0.1,0.1,.5,.5])
plt.xticks([]), plt.yticks([])
plt.text(0.1,0.1, 'axes([0.1,0.1,.5,.5])',ha='left',va='center',size=16,alpha=.5)

plt.axes([0.2,0.2,.5,.5])
plt.xticks([]), plt.yticks([])
plt.text(0.1,0.1, 'axes([0.2,0.2,.5,.5])',ha='left',va='center',size=16,alpha=.5)

plt.axes([0.3,0.3,.5,.5])
plt.xticks([]), plt.yticks([])
plt.text(0.1,0.1, 'axes([0.3,0.3,.5,.5])',ha='left',va='center',size=16,alpha=.5)

plt.axes([0.4,0.4,.5,.5])
plt.xticks([]), plt.yticks([])
plt.text(0.1,0.1, 'axes([0.4,0.4,.5,.5])',ha='left',va='center',size=16,alpha=.5)

# plt.savefig("../figures/axes-2.png",dpi=64)
plt.show()

记号

格式正确的刻度线是发布准备图的重要部分。 Matplotlib为tick提供了一个完全可配置的系统。刻度线定位器可以指定刻度线应出现的位置,刻度线格式器可以让刻度线显示所需的外观。主刻度线和次刻度线可以彼此独立地定位和格式化。默认情况下,不显示次要记号,即只有一个空列表,因为它作为NullLocator(见下文)。

刻度线定位器

有几种针对不同类型需求的定位器:

类型描述
NullLocator无刻度线在这里插入图片描述
IndexLocator在绘制的基本点数的每个倍数上打勾在这里插入图片描述
FixedLocator修改刻度线位置在这里插入图片描述
LinearLocator确定刻度位置在这里插入图片描述
MultipleLocator在每个整数倍的基数上设置一个刻度在这里插入图片描述
AutoLocator在合适的位置选择不超过n个间隔。在这里插入图片描述
LogLocator确定对数轴的刻度位置。在这里插入图片描述

所有这些定位器均源自基类matplotlib.ticker.Locator。您可以从中派生自己的定位器。将日期作为刻度记号可能会特别棘手。因此,matplotlib在matplotlib.dates中提供了特殊的定位符。

4、动画

长期以来,matplotlib中的动画制作不是一件容易的事,并且主要是通过巧妙的技巧来完成的。但是,自1.1版和引入用于直观地创建动画的工具以来,情况已经开始发生变化,并且可以将它们保存为各种格式(但是不要指望能够以60 fps的速度运行非常复杂的动画)。

文献资料

在matplotlib中制作动画最简单的方法是声明一个FuncAnimation对象,该对象向matplotlib指定要更新的图形,更新函数是什么以及帧之间的延迟是什么。

雨滴滴落

通过将小的生长环随机放置在图形上,可以获得非常简单的降雨效果。当然,它们不会永远增长,因为波浪应该随着时间而衰减。为了模拟这一点,我们可以在环增长时使用越来越透明的颜色,直到不再可见为止。在这一点上,我们删除环并创建一个新环。

第一步是创建一个空白图:

# New figure with white background
fig = plt.figure(figsize=(6,6), facecolor='white')

# New axis over the whole figure, no frame and a 1:1 aspect ratio
ax = fig.add_axes([0,0,1,1], frameon=False, aspect=1)

接下来,我们需要创建几个环。为此,我们可以使用通常用于可视化点云的散点图对象,但也可以通过指定我们没有脸色来使用它来绘制圆环。我们还必须注意每个环的初始尺寸和颜色,以使所有尺寸都在最小尺寸和最大尺寸之间。另外,我们需要确保最大的环几乎是透明的。

在这里插入图片描述

# Number of ring
n = 50
size_min = 50
size_max = 50*50

# Ring position
P = np.random.uniform(0,1,(n,2))

# Ring colors
C = np.ones((n,4)) * (0,0,0,1)
# Alpha color channel goes from 0 (transparent) to 1 (opaque)
C[:,3] = np.linspace(0,1,n)

# Ring sizes
S = np.linspace(size_min, size_max, n)

# Scatter plot
scat = ax.scatter(P[:,0], P[:,1], s=S, lw = 0.5,
                  edgecolors = C, facecolors='None')

# Ensure limits are [0,1] and remove ticks
ax.set_xlim(0,1), ax.set_xticks([])
ax.set_ylim(0,1), ax.set_yticks([])

现在,我们需要为动画编写更新功能。我们知道,在每个时间步长,每个环都应增长并变得更加透明,而最大的环应完全透明并因此被去除。当然,我们实际上不会删除最大的圆环,而是重新使用它来将新的圆环设置在标称大小和颜色的新随机位置。因此,我们保持环数不变。

在这里插入图片描述

def update(frame):
    global P, C, S

    # Every ring is made more transparent
    C[:,3] = np.maximum(0, C[:,3] - 1.0/n)

    # Each ring is made larger
    S += (size_max - size_min) / n

    # Reset ring specific ring (relative to frame number)
    i = frame % 50
    P[i] = np.random.uniform(0,1,2)
    S[i] = size_min
    C[i,3] = 1

    # Update scatter object
    scat.set_edgecolors(C)
    scat.set_sizes(S)
    scat.set_offsets(P)

    # Return the modified object
    return scat,

最后一步是告诉matplotlib使用此函数作为动画的更新函数,并显示结果或将其保存为电影:

animation = FuncAnimation(fig, update, interval=10, blit=True, frames=200)
# animation.save('rain.gif', writer='imagemagick', fps=30, dpi=40)
plt.show()

地震

现在,我们将使用rain动画来可视化过去30天以来地球上的地震。 USGS地震危害计划是国家减少地震危害计划(NEHRP)的一部分,并在其网站上提供了一些数据。这些数据是根据地震震级排序的,范围从仅严重到所有大,小地震。您会惊讶于地球上每小时发生的小地震次数。由于这对我们来说将代表太多数据,因此我们将坚持4.5级以上的地震。在撰写本文时,这已经代表了过去30天内的300多场地震。

第一步是读取和转换数据。我们将使用urllib库,该库允许我们打开和读取远程数据。网站上的数据使用CSV格式,其内容由第一行给出:

time,latitude,longitude,depth,mag,magType,nst,gap,dmin,rms,net,id,updated,place,type
2015-08-17T13:49:17.320Z,37.8365,-122.2321667,4.82,4.01,mw,...
2015-08-15T07:47:06.640Z,-10.9045,163.8766,6.35,6.6,mwp,...

我们仅对纬度,经度和大小感兴趣。

import urllib
from mpl_toolkits.basemap import Basemap

# -> http://earthquake.usgs.gov/earthquakes/feed/v1.0/csv.php
feed = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/"

# Significant earthquakes in the last 30 days
# url = urllib.request.urlopen(feed + "significant_month.csv")

# Magnitude > 4.5
url = urllib.request.urlopen(feed + "4.5_month.csv")

# Magnitude > 2.5
# url = urllib.request.urlopen(feed + "2.5_month.csv")

# Magnitude > 1.0
# url = urllib.request.urlopen(feed + "1.0_month.csv")

# Reading and storage of data
data = url.read()
data = data.split(b'\n')[+1:-1]
E = np.zeros(len(data), dtype=[('position',  float, 2),
                               ('magnitude', float, 1)])

for i in range(len(data)):
    row = data[i].split(',')
    E['position'][i] = float(row[2]),float(row[1])
    E['magnitude'][i] = float(row[4])

现在,我们需要在图形上绘制地球以精确显示地震中心在哪里,并在matplotlib可以处理的某些坐标中转换纬度/经度。幸运的是,确实有一个易于安装和使用的basemap项目(倾向于由更完整的cartopy代替)。第一步是定义一个投影以将地球绘制到屏幕上(存在许多不同的投影),我们将坚持使用磨机投影,这对于像我这样的非专业人士来说是相当标准的。

fig = plt.figure(figsize=(14,10))
ax = plt.subplot(1,1,1)

earth = Basemap(projection='mill')

接下来,我们要求绘制海岸线并填充各大洲:

earth.drawcoastlines(color='0.50', linewidth=0.25)
earth.fillcontinents(color='0.95')

地球对象也将用于自动转换坐标。我们快完成了。最后一步是调整rain代码,并添加一些注意事项:

P = np.zeros(50, dtype=[('position', float, 2),
                         ('size',     float, 1),
                         ('growth',   float, 1),
                         ('color',    float, 4)])
scat = ax.scatter(P['position'][:,0], P['position'][:,1], P['size'], lw=0.5,
                  edgecolors = P['color'], facecolors='None', zorder=10)

def update(frame):
    current = frame % len(E)
    i = frame % len(P)

    P['color'][:,3] = np.maximum(0, P['color'][:,3] - 1.0/len(P))
    P['size'] += P['growth']

    magnitude = E['magnitude'][current]
    P['position'][i] = earth(*E['position'][current])
    P['size'][i] = 5
    P['growth'][i]= np.exp(magnitude) * 0.1

    if magnitude < 6:
        P['color'][i]    = 0,0,1,1
    else:
        P['color'][i]    = 1,0,0,1
    scat.set_edgecolors(P['color'])
    scat.set_facecolors(P['color']*(1,1,1,0.25))
    scat.set_sizes(P['size'])
    scat.set_offsets(P['position'])
    return scat,


animation = FuncAnimation(fig, update, interval=10)
plt.show()

如果一切顺利,您应该获得以下内容(带有动画):

在这里插入图片描述

5、快速参考

这是一组显示主要属性和样式的表。

线属性

属性描述外观
alpha (or a)0-1比例的alpha透明度在这里插入图片描述
antialiasedTrue or False - 使用抗锯齿渲染在这里插入图片描述
color (or c)Matplotlib颜色在这里插入图片描述
linestyle (or ls)参考 Line properties
linewidth (or lw)浮点,以点为单位的线宽在这里插入图片描述
solid_capstyle实线的封口样式在这里插入图片描述
solid_joinstyle实线的连接样式在这里插入图片描述
dash_capstyle虚线的封口样式在这里插入图片描述
dash_joinstyle虚线的连接样式在这里插入图片描述
marker参考Markers
markeredgewidth (mew)标记符号周围的线宽在这里插入图片描述
markeredgecolor (mec)边缘颜色(如果使用标记)在这里插入图片描述
markerfacecolor (mfc)面部颜色(如果使用标记)在这里插入图片描述
markersize (ms)标记的大小(以点为单位)在这里插入图片描述

线条样式

在这里插入图片描述

标记

在这里插入图片描述

色彩图

可以通过附加_r反转所有颜色图。例如,gray_r是灰色的反面。
如果您想了解有关颜色图的更多信息,请参阅记录matplotlib颜色图
.
基础
在这里插入图片描述

GIST

在这里插入图片描述

发散
在这里插入图片描述

顺序
在这里插入图片描述

定性
在这里插入图片描述

杂项

在这里插入图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值