当我们想对图形做出一些注释和说明时,可以使用注解annotate,相对应的面向对象的实例方法是Axes.annotate()。注解本身也有作用对象之分,有对细节做出标志的有指示注解和对整体做出说明的无指示注解两类。
有指示注解是通过箭头的指示的方法对绘图区域中的内容进行解释的标注方法。无指示注解是单纯使用文本进行内容注释或是说明的标注方法。
1.有指示注解和无指示注解的添加方法
有指示注解和无指示注解主要通过函数annotate()和text()来实现。
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0.5,3.5,100)
y = np.sin(x)
fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot(111)
# set subplot
ax.plot(x,y,c="b",ls="--",lw=2)
# Annotate the point xy with text with the "arrowstyle"
ax.annotate("maximum",xy=(np.pi/2,1.0),xycoords="data",
xytext=((np.pi/2)+0.15,0.8),textcoords="data",
arrowprops=dict(arrowstyle="->",
connectionstyle="arc3",
color="r"))
# Annotate the whole points with text without the "arrowstyle"
# Add test to the axes
ax.text(2.8,0.4,"$y=\sin(x)$",fontsize=20,color="b",
bbox=dict(facecolor='y',alpha=0.5))
plt.show()
首先生成实例ax,然后绘制折线图ax.plot()。通过调用
ax.annotate(s,xy,xycoords,xytext,textcoords,weight,color,arrowprops)
语句来实现绘制有指示注解的目标
s:注解的内容
xy:需要进行解释的位置
xycoords:xy的坐标系统,参数值“data”表示与折线图使用相同的坐标系统
xytext:注释内容所在位置,如果把注释内容想象为一个矩形,xytext标记的是左下角顶点的位置
textcoords:xytext的坐标系统
weight:注解内容的显示风格
color:注解内容的颜色
arrowprops:指示箭头的属性,包括箭头风格、颜色等
对折线图顶点进行详细的解释后,我们需要对折线图本身加以说明,告诉大家这是一条正弦曲线的局部。这时候就需要添加无指示注解。通过调用ax.text(x,y,s,**kw)实例方法来完成。
x,y:注解的横纵坐标,如果把注释内容想象为一个矩形,x,y标记的是左下角顶点的内容。
s:注解内容。
值得注意的是,有指示注解和无指示注解主要区别是有无箭头显示,也就是对被解释内容的精确定位。
2.圆角文本框设置
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0.0,10,40)
y = np.random.randn(40)
plt.plot(x,y,ls="-",lw=2,
marker="o",
ms=20,
mfc="orange",
alpha=0.6)
plt.grid(ls=":",color="gray",alpha=0.5)
plt.text(6,0,"Matplotlib",size=30,rotation=30,
bbox=dict(boxstyle="round",
ec="#8968CD",
fc="#FFEEFF"))
plt.show()
圆角文本框“Matplotlib”的效果是通过Rectangle属性字典bbox实现的,具体是使用关键字参数bbox的字典参数值中的
键值对“boxstyle=round”实现的,其中的键值还可以改为“square”,进而形成直角线框的效果。
3.文本的水印效果
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0.0,10,40)
y = np.random.randn(40)
plt.plot(x,y,ls="-",lw=2,
marker="o",
ms=20,
mfc="orange",
alpha=0.6)
plt.grid(ls=":",color="gray",alpha=0.5)
plt.text(1,2,"Matplotlib",fontsize=50,color="gray",alpha=0.5)
plt.show()
文本的水印效果是通过text()中的关键字参数alpha的设定来实现的。关键字alpha的取值越小,文本的水印效果越明显。
3.圆角线框的有弧度指示的注解
将指示箭头出现转角的可视化效果。
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0,10,2000)
y = np.sin(x)*np.cos(x)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,y,ls="-",lw=2)
bbox = dict(boxstyle="round",fc="#7EC0EE",ec="#9B30FF")
arrowprops = dict(arrowstyle="-|>",
connectionstyle="angle,angleA=10,angleB=60,rad=10",
color="r")
ax.annotate("single point",
(5,np.sin(5)*np.cos(5)),
xytext=(3,np.sin(3)*np.cos(3)),
fontsize=12,color="r",
bbox=bbox,arrowprops=arrowprops)
ax.grid(ls=":",color="gray",alpha=0.6)
plt.show()
plt.show()
有弧度的注解通过arrowprops中的
connectionstyle=“angle,angleA=10,angleB=60,rad=10”,来实现
4.有箭头指示的群实现
一方面可以单一地展示指示箭头而将注解隐藏,从而产生只有指示箭头的展示效果,进而用这种没有文本的指示箭头作为趋势线来反映折线的趋势变化和周期规律。另一方面,也可以通过使用其它方法实现有指示箭头作为趋势线的可视化需求。
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0,10,2000)
y = np.sin(x)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,y,ls="-",lw=2)
ax.set_ylim(-1.5,1.5)
arrowprops = dict(arrowstyle="-|>",color="r")
ax.annotate("",
(3*np.pi/2,np.sin(3*np.pi/2)+0.05),
xytext=(np.pi/2,np.sin(np.pi/2)+0.05),
color="r",
arrowprops=arrowprops)
ax.arrow(0.0,-0.4,np.pi/2,1.2,
head_width=0.05,head_length=0.1,
fc='g',ec='g')
ax.grid(ls=":",color="gray",alpha=0.6)
plt.show()
plt.show()
使用Axes的实例方法arrow(绘制出绿色的箭头,但是箭头不是正三角形),借助Axes的实例方法annotate()可以绘制处没有注解的指示箭头,而且箭头是正三角形的。实例方法arrow(x,y,dx,dy)中的参数dx是参数x的水平增量,参数dy是参数y的垂直增量。
6.桑基图
有指示注解不仅可以用来作为图形内容的注释,还可以抽象为一种图形。这种图形就是桑基图,桑基图是一种特定类型的流量图。在流量图中,指示箭头的宽度与流量的大小成比例。流量图的典型应用场景是可视化呈现能量、物质或是成本在流动过程中的转移情况。
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
from matplotlib.sankey import Sankey
mpl.rcParams["font.sans-serif"]=["FangSong"]
mpl.rcParams["axes.unicode_minus"]=False
flows=[0.2,0.1,0.4,0.3,-0.6,-0.05,-0.15,-0.2]
labels=["","","","","family","trip","education","sport"]
orientations=[1,1,0,-1,1,-1,1,0]
sankey = Sankey()
sankey.add(flows=flows,
labels=labels,
orientations=orientations,
color="c",
fc="lightgreen",
patchlabel="Life cost",
alpha=0.7)
diagrams = sankey.finish()
diagrams[0].texts[4].set_color("r")
diagrams[0].texts[4].set_weight("bold")
diagrams[0].text.set_fontsize(20)
diagrams[0].text.set_fontweight("bold")
plt.title("日常生活成本开支的流量图")
plt.show()
调用语句Sankey()生成实例sankey,然后分别调用实例方法add()和finish()完成桑基图的基础绘制工作,列表flows中的负值表示流出量,正值表示流入量。列表中orientations中的-1,0和1分别表示流量的显示位置在下方、水平和上方。最后调整流量图diagrams[0]的文本“List Cost”和“family”的显示样式、颜色等属性的属性值。