Matplotlib系列目录
matplotlib中路径(Path)、面片/块(Patch)和集合(Collection)可以实现简单几何图形的绘制,并且可以组合成为更加高级的图形,matplotlib二维、三维中很多图形就是基于路径、块和集合实现的,比如箭头、非结构三角网格面等。
通常只需要指到预定义的块形状(圆、矩形、多边形等)的用法即可,其他了解一下,需要用的时候再查看帮助就ok。
Matplotlib系列将Matplotlib的知识和重点API,编制成思维导图和重点笔记形式,方便记忆和回顾,也方便应用时参考,初学者也可以参考逐步深入学习。
在Matplotlib中所有图形都是Artist对象,事实上连Figure和Axes也是Artist对象。
Path主要用于组成Patch。Path不能直接在图形中显示。可以用ax.add_patch()函数把Patch添加到坐标系中显示。
matplotlib预定义一部分Patch。包括
所有预定义patch类都在mtplotlib.patches
中。比如mtplotlib.patches.Circle。
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
fig = plt.figure()
ax = fig.subplots()
#circle1=Circle((2,2),1)
circle1=Circle((2,2),1,fc='C2',ec='0.5',lw=2,alpha=0.5)
ax.add_patch(circle1)
ax.axis([0,4,0,4]) #设置x,y轴范围,坐标系不会自动根据patch调整。
ax.set_aspect(1) #x,y轴显示比例不随窗口改变。
plt.show()
matplotlib中很多函数同时有color,facecolor和edgecolor参数。color参数表示同时设置facecolor和edgecolor。facecolor和edgecolor优先级更高,通常设置这两个参数就ok了。
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
fig = plt.figure()
ax = fig.subplots()
#rect1=Rectangle((1,1),2,1)
rect1=Rectangle((1,1),2,1,fc='C3',ec='0.5',lw=2,alpha=0.5)
ax.add_patch(rect1)
ax.axis([0,4,0,3]) #设置x,y轴范围,坐标系不会自动根据patch调整。
ax.set_aspect(1) #x,y轴显示比例不随窗口改变。
plt.show()
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse
fig = plt.figure()
ax = fig.subplots()
#e1=Ellipse((2,1.5),2,1)
e1=Ellipse((1,2),1.5,1,45)
e2=Ellipse((2,1.5),2,1,fc='C8',ec='C0',lw=2,alpha=0.5)
ax.add_patch(e1)
ax.add_patch(e2)
ax.axis([0,4,0,3]) #设置x,y轴范围,坐标系不会自动根据patch调整。
ax.set_aspect(1) #x,y轴显示比例不随窗口改变。
plt.show()
圆弧实际上就是椭圆函数增加了theta1和theta2参数,即圆弧起止角度。
import matplotlib.pyplot as plt
from matplotlib.patches import Arc
fig = plt.figure()
ax = fig.subplots()
arc1=Arc((1,2),1.5,1)
arc2=Arc((2,1.5),2,1,0,30,120,ec='r')
arc3=Arc((2,1.5),2,1,theta1=200,theta2=300,color='g') #color不能缩写为c
ax.add_patch(arc1)
ax.add_patch(arc2)
ax.add_patch(arc3)
ax.axis([0,4,0,3]) #设置x,y轴范围,坐标系不会自动根据patch调整。
ax.set_aspect(1) #x,y轴显示比例不随窗口改变。
plt.show()
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
fig = plt.figure()
ax = fig.subplots()
pts=np.array([[0,0],[1,1],[1,0]])
p1=Polygon(pts)
p2=Polygon(np.array([[0,2],[1,2],[2,3]]),color="g")
p3=Polygon(np.array([[2,2],[3,2],[3,1]]),fc="C4",ec='C1')
ax.add_patch(p1)
ax.add_patch(p2)
ax.add_patch(p3)
ax.axis([0,4,0,3]) #设置x,y轴范围,坐标系不会自动根据patch调整。
ax.set_aspect(1) #x,y轴显示比例不随窗口改变。
plt.show()
RegularPolygon(xy, numVertices, radius=5, orientation=0)
:绘制正多边形
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import RegularPolygon
fig = plt.figure()
ax = fig.subplots()
p1=RegularPolygon([1,1.5],4,0.8)
p2=RegularPolygon([3,1.5],5,0.8,np.pi/2,color="g",ec='r',alpha=0.5)
ax.add_patch(p1)
ax.add_patch(p2)
ax.axis([0,4,0,3]) #设置x,y轴范围,坐标系不会自动根据patch调整。
ax.set_aspect(1) #x,y轴显示比例不随窗口改变。
plt.show()
内径为r-width,外径为r。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Annulus
fig = plt.figure()
ax = fig.subplots()
a1=Annulus([1,2],0.8,0.2)
a2=Annulus([3,2],1,0.2,50, fc="0.5",ec='r',alpha=0.5)
ax.add_patch(a1)
ax.add_patch(a2)
ax.axis([0,4,0,4]) #设置x,y轴范围,坐标系不会自动根据patch调整。
ax.set_aspect(1) #x,y轴显示比例不随窗口改变。
plt.show()
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Wedge
fig = plt.figure()
ax = fig.subplots()
a1=Wedge([1,2],0.8,90,120)
a2=Wedge([3,2],1,45,180, 0.5, fc="0.5",ec='r',alpha=0.5)
ax.add_patch(a1)
ax.add_patch(a2)
ax.axis([0,4,0,4]) #设置x,y轴范围,坐标系不会自动根据patch调整。
ax.set_aspect(1) #x,y轴显示比例不随窗口改变。
plt.show()
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Circle,Shadow
fig = plt.figure()
ax = fig.subplots()
c1=Circle([1,2],0.8)
c2=Circle([3,2],0.8,color='g')
s1=Shadow(c2,0.05,-0.05,lw=0)
ax.add_patch(c1)
ax.add_patch(c2)
ax.add_patch(s1)
ax.axis([0,4,0,4]) #设置x,y轴范围,坐标系不会自动根据patch调整。
ax.set_aspect(1) #x,y轴显示比例不随窗口改变。
plt.show()
patch由path和填充组成,创建path后,用matplotlib.patches中的PathPatch可以生成patch。
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch
fig = plt.figure()
ax = fig.add_subplot()
path = Path.circle([2,2],1) #创建path
patch = PathPatch(path, facecolor='orange', lw=2) #根据path创建patch
ax.add_patch(patch)
ax.axis([0,4,0,4])
ax.set_aspect(1)
plt.show()
Path类支持以下方法创建预定义path:
注意上述预定义path都在坐标原点,没法直接修改,可以作为plot函数marker等参数的值。
文本也可以创建path。文本path相比文本可以实现更多功能,比如特效、蒙版等。
matplotlib.textpath.TextPath([1,40],"textpath")
:在指定位置创建文本pathimport numpy as np
import matplotlib.pyplot as plt
from matplotlib.textpath import TextPath
from matplotlib.patches import PathPatch
fig = plt.figure()
ax = fig.subplots()
t1=TextPath([1,40],"textpath")
t2=TextPath([1,25],"textpath2",8) #指定文本大小,单位和坐标系相同
t3=TextPath([1,10],"$e^{i\pi}+1=0$",usetex=True) #指定是否使用latex公式。
ax.add_patch(PathPatch(t1,fc='r'))
ax.add_patch(PathPatch(t2,fc='g'))
ax.add_patch(PathPatch(t3,fc='b'))
ax.axis([0,50,0,50]) #设置x,y轴范围,坐标系不会自动根据patch调整。
ax.set_aspect(1) #x,y轴显示比例不随窗口改变。
plt.show()
路径Path实例实际上是一组(N,2)数组表示的(x,y)点和一个长度为N的包含命令的数组组成。
路径支持一组标准的命令,用于绘制曲线段和样条曲线,可以组成简单和复合轮廓。命令包括:moveto、lineto、curveto等。指定点坐标和命令就可以创建自定义路径。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch
fig = plt.figure()
ax = fig.subplots()
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)
patch = PathPatch(path,fc='C4')
ax.add_patch(patch)
ax.axis([-1,2,-1,2])
ax.set_aspect(1)
plt.show()
文本特效
import matplotlib.pyplot as plt
from matplotlib import patheffects
fig = plt.figure()
ax = fig.subplots()
text = ax.text(0.1, 0.5, 'Hello world!', size=20)
text.set_path_effects([patheffects.Normal()])
plt.show()
绘图特效
import matplotlib.pyplot as plt
from matplotlib import patheffects
fig = plt.figure()
ax = fig.subplots()
ax.plot([0,3,2,4], path_effects=[patheffects.Normal()])
plt.show()
Normal特效表示没有任何效果。
常见特效
在matplotlib.patheffects中有定义好的特效类:
import matplotlib.pyplot as plt
from matplotlib import patheffects
from matplotlib.patheffects import Normal,PathPatchEffect, SimpleLineShadow,Stroke,TickedStroke
fig = plt.figure()
ax = fig.subplots()
#线条阴影
ax.plot([0,10,20,30],[0,5,2,10],lw=3,path_effects=[SimpleLineShadow(),Normal()])
#文本轮廓
text1 = ax.text(1,15,'text stands out',size=30,c='0.8')
text1.set_path_effects([Stroke(linewidth=1, foreground='C0')]) #描边特效
#文本填充阴影
text2 = ax.text(1, 30, 'Hatch shadow',size=40,weight=800)
text2.set_path_effects([PathPatchEffect((4,-4),hatch='xxxx'),PathPatchEffect(fc='w',lw=1)])
ax.axis([0,50,0,50])
plt.show()
把指定路径设置为蒙版,只显示路径内的图形。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.text import TextPath
fig = plt.figure()
ax = fig.subplots()
textpath=TextPath((1,20),'textpath',prop={'weight':1000})
img=ax.imshow(np.random.randn(50,50),interpolation="bilinear")
img.set_clip_path(textpath,img.get_transform())
ax.axis([0,50,0,50])
plt.show()
绘制大量图形时,可以使用集合Collection。
Collection类派生类的各种集合对象可以用于绘制图形集合。
用线条集合可以同时绘制大量颜色位置长度不同的线条,可以绘制出非常复杂的图形,比如蝴蝶、动物等。
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.collections import EllipseCollection
fig=plt.figure()
ax = fig.subplots()
ws = np.full(3,15)
hs = np.full(3,10)
angles = np.arange(3)*30
offsets= np.array([[10,10],[20,20],[30,30]])
ec = EllipseCollection(ws, hs, angles,offsets=offsets,transOffset=ax.transData)
#ws为椭圆宽度,hs为椭圆高度,angles为椭圆旋转角度,offsets为椭圆位置
ax.add_collection(ec)
ax.axis([0,50,0,50])
plt.show()
Matplotlib系列目录
个人总结,部分内容进行了简单的处理和归纳,如有谬误,希望大家指出,持续修订更新中。
修订历史版本见:https://github.com/hustlei/AI_Learning_MindMap
未经允许请勿转载。