装金饰指的是你可以添加到一个图形上的全部额外元素,以美化它或使它更清楚。装金饰包罗图例、解释、颜色条、文本等标准元素,但也可以专门计划本身的元素。上篇Matplotlib可视化之解释与文本高级应用一文中,已经打仗了解释与文本的应用实例,本日和云朵君一起继承学习图例与标签元素的应用实例。
设置图例
想在可视化图形中利用图例,可以为差别的图形元素分配标签。
图例非常轻易利用,只要求用户定名图。Matplotlib将主动创建一个包罗每个图形元素的图例。纵然在大多数环境下,一个简单的legend()调用就充足了,但图例还是提供了几个选项,答应我们自界说图例的各个设置。如利用
ax.legend(loc='upperleft',
frameon=False,
edgecolor="None")
完备代码分析
fig=plt.figure(figsize=(9.6,4))
ax=plt.subplot(
xlim=[-np.pi,np.pi],
xticks=[-np.pi,-np.pi/2,0,np.pi/2,np.pi],
xticklabels=["$-\pi$","$-\pi/2$","0","$+\pi/2$","$+\pi$"],
ylim=[-1,1],
yticks=[-1,0,1],
yticklabels=["-1","0","+1"],
)
X=np.linspace(-np.pi,np.pi,256,endpoint=True)
C,S=np.cos(X),np.sin(X)
#绘制两条折线,颜色默认
ax.plot(X,C,label="$cos(x)$",clip_on=False)
ax.plot(X,S,label="$sin(x)$",clip_on=False)
#隐蔽上右边的轴线
ax.spines["right"].set_visible(False)
ax.spines["top"].set_visible(False)
#移动下左边的轴线
ax.spines["left"].set_position(("data",-3.25))
ax.spines["bottom"].set_position(("data",-1.25))
ax.legend(edgecolor="None",loc=2,frameon=False)
然而,在某些环境下,用图例来添加信息大概不是最符合的方式。比方,当你有多个图表时,读者在阅读图表,视线在图表和图例之间来回切换时,大概会以为很乏味。另一种可以办理此类狐疑的方法是在下图所示的图上直接添加信息。
具体代码分析
X=np.linspace(-np.pi,np.pi,400,endpoint=True)
C,S=np.cos(X),np.sin(X)
plot1,plot2=plot(ax)#绘制折线图的对象
#--------------------P1-------------------------
#用小横线标注在折线旁边
ax.text(
X[-1],C[-1],
"—"+plot1.get_label(),#从对象中获取标签
color=plot1.get_color(),#从对象中获取线条颜色
size="small",ha="left",va="center",)
#--------------------P2--------------------------
#标注在对应折线上,且有透明边框
ax.text(
X[100],C[100],
""+plot1.get_label(),
bbox=dict(facecolor="white",edgecolor="None",alpha=0.85),
color=plot1.get_color(),
ha="center",va="center",size="small",
rotation=42.5,)
#--------------------P3--------------------------
#利用箭头
ax.annotate(
"$cos(x)$",
(X[100],C[100]),
size="medium",
color=plot1.get_color(),
xytext=(-50,+10),
textcoords="offsetpoints",
arrowprops=dict(
arrowstyle="-",color=plot1.get_color(),
connectionstyle="arc3,rad=-0.3"),)
#--------------------P4--------------------------
#圈点和解释的组合
index=10
ax.scatter(
[X[index]],[C[index]],
s=100,marker="o",zorder=10,
edgecolor=plot1.get_color(),
facecolor="white",linewidth=1,clip_on=False,)
ax.text(
X[index],1.01*C[index],
"A",
zorder=20,size="small",
color=plot1.get_color(),
ha="center",va="center",clip_on=False,)
固然,这里是没有最好的选择,由于它真的取决于数据。对于上述的sin/cos的示例(非常简单),这四种办理方案都是符合的,但当有很多实际数据一起利用时,大概这种方法就失效了。此时我们大概必要寻求其他方式来标记数据,如将图分成几个图分别展示。
标题和标签
我们已经利用set_title、set_xlabel和set_ylabel方法操纵了标题和标签。当仅仅利用默认参数时,确实比力方便。而且它们的默认位置通常对大多数图表都比力符合。只管云云,仍旧可以利用各种参数来定制和美化图形。
如下面两个图所示,对比观察,可以显着发现:上图大部分利用了默认参数。而下图中,用轴标签更换轴刻度标签,即在轴中心加上阐明标签,为了使其更靠近轴,删除了大概与标签碰撞的中心刻度。别的,将标题其向右移动,并相应地移动图例框,将其放置在标题下方,而且利用一行两列的分列方式。着实这里没有做过复杂的操纵,但我以为结果在视觉上更惊艳。
完备代码分析
ax.legend(
edgecolor="None",
ncol=2,
loc="upperright",
bbox_to_anchor=(1.01,1.225),
#用于与loc一起定位图例的框。(x,y,width,height)
borderaxespad=1,
#轴线和图例边框之间的添补,以字体巨细为单位。
)
#设置标题
ax.set_title("三角函数",x=1,y=1.2,ha="right",size=14)
#设置x轴标签
ax.set_xlabel("角度",va="center",weight="bold",size=12)
ax.xaxis.set_label_coords(0.5,-0.25)
#设置标签的坐标。
#默认环境下,y标签的x坐标和x标签的y坐标由刻度标签边界框确定,
#但是假如有多个轴,这大概会导致多个标签对齐不良。
#设置y轴标签
ax.set_ylabel("值",ha="center",weight="bold",size=12)
ax.yaxis.set_label_coords(-0.025,0.5)
在某些环境下(如集会会议海报),大概必要让标题更吸引眼球,如下图所示。这可以通过利用make_axes_locatable方法来分别每个轴,并为标题地区预留15%的高度。在这个图中,还用Latex插入了一个完全对齐的文本,它可以被看作是另一种情势或(高级)装饰。
完备代码拜见latex-text-box[1]
解释
在matplotlib中,解释大概是最难处理惩罚的对象。缘故起因是它包罗的概念浩繁,而这些概念又具有大量的参数。别的,由于解释所涉及的文本巨细是按点分列的,这无疑又是落井下石。别的大概必要肴杂利用像素、点、分数或数据单位中的绝对坐标或相对坐标。你可以这么以为,你可以对具有任何范例投影的任何轴举行解释,那么你如今应该可以明白到为什么annotate方法提供这么多参数。
上面这段话比力抽象,接下来我们一起看下具体例子。解释图形最简单的方法是在想要解释的点附近添加标签,如下图所示。图中,为了使得标签独立于数据分布保持可读性,为标签添加了一个白色的表面。然而,假如如许的点过多,全部差别的标签大概会使图形变得紊乱,并大概会粉饰潜伏的紧张信息。
完备代码分析
importmatplotlib.patheffects
aspath_effects
fig=plt.figure(figsize=(10,5))
ax=plt.subplot(1,2,1,xlim=[-1,+1],
xticks=[],ylim=[-1,+1],
yticks=[],aspect=1)
#---------------------------------------------
#绘制散点图
np.random.seed(123)
X=np.random.normal(0,0.35,1000)
Y=np.random.normal(0,0.35,1000)
ax.scatter(X,Y,edgecolor="None",s=60,
facecolor="C1",alpha=0.5)
#不重复采取:array([1,4,0,3,2])
I=np.random.choice(len(X),size=5,
replace=False)
#根据y值,从大到小排序
Px,Py=X[I],Y[I]
I=np.argsort(Y[I])[::-1]
Px,Py=Px[I],Py[I]
#将随机选取的五个点用玄色边框框选出
ax.scatter(Px,Py,edgecolor="black",facecolor="white",zorder=20)
ax.scatter(Px,Py,edgecolor="None",facecolor="C1",alpha=0.5,zorder=30)
添加标签解释
fori
inrange(len(I)):
#五个解释是样式是一样的,可以利用循环添加
text=ax.annotate(
"Point"+chr(ord("A")+i),
xy=(Px[i],Py[i]),
xycoords="data",
xytext=(0,18),
textcoords="offsetpoints",
ha="center",
size="medium",
arrowprops=dict(
arrowstyle="-",shrinkA=0,shrinkB=5,color="black",linewidth=0.75),
)
text.set_path_effects(
[path_effects.Stroke(linewidth=2,foreground="white"),path_effects.Normal()]
)
text.arrow_patch.set_path_effects(
[path_effects.Stroke(linewidth=2,foreground="white"),path_effects.Normal()]
)
另一种方法是将标签推到图的一侧,并利用虚线来创建点和标签之间的链接,如下图所示。
但这些外形、位置、分列方式等样式的计划并不是图形主动的,为了绘制出该图形,就必须盘算险些全部的东西。
起首,为了不让线相互交错,将目标标记的点排序:
X=np.random.normal(0,.35,1000)
Y=np.random.normal(0,.35,1000)
ax.scatter(X,Y,edgecolor="None",
facecolor="C1",alpha=0.5)
I=np.random.choice(len(X),size=5,replace=False)
Px,Py=X[I],Y[I]
I=np.argsort(Y[I])[::-1]
Px,Py=Px[I],Py[I]
从这些点开始,利用一个相称复杂的毗连样式来解释它们:
y,dy=0.25,0.125
style="arc,angleA=-0,angleB=0,armA=-100,armB=0,rad=0"
fori
inrange(len(I)):
text=ax2.annotate(
"Point"+chr(ord("A")+i),
xy=(Px[i],Py[i]),
xycoords="data",
xytext=(1.25,y-i*dy),
textcoords="data",
arrowprops=dict(
arrowstyle="-",
color="black",
linewidth=0.75,
shrinkA=20,
shrinkB=5,
patchA=None,
patchB=None,
connectionstyle=style,
),
)
text.arrow_patch.set_path_effects(
[path_effects.Stroke(linewidth=2,foreground="white"),path_effects.Normal()]
)
也可以利用毗连补片的方式在轴外来解释的目标对象,如下图所示。
该图中,创建了几个矩形,在一些点四周表现感爱好的地区,并创建了与相应的缩放轴的毗连。留意毗连开始在表面的矩形,这是一个不错的功能提供的解释:可以指定对象的性子要解释(通过提供一个patche)和matplotlib会照顾的毗连边界的劈头的patche。
完备代码分析
frommatplotlib.gridspec
importGridSpec
frommatplotlib.patches
importRectangle,ConnectionPatch
#设置画布
fig=plt.figure(figsize=(6,5))
n=5
gs=GridSpec(n,n+1)
ax=plt.subplot(gs[:n,:n],
xlim=[-1,+1],xticks=[],
ylim=[-1,+1],yticks=[],aspect=1)
#绘制散点图略(见上面代码)
dx,dy=0.075,0.075
fori,(x,y)
inenumerate(zip(Px,Py)):
#设置子画布
sax=plt.subplot(
gs[i,n],
xlim=[x-dx,x+dx],
xticks=[],
ylim=[y-dy,y+dy],
yticks=[],
aspect=1,)
#在子画布上绘制散点
sax.scatter(X,Y,edgecolor="None",
facecolor="C1",alpha=0.5,s=60)
sax.scatter(Px,Py,edgecolor="black",
facecolor="None",linewidth=0.75,s=60)
#加上解释
sax.text(
1.1,0.5,
"Point"+chr(ord("A")+i),
rotation=90,size=8,ha="left",va="center",
transform=sax.transAxes,)
#绘制矩形
rect=Rectangle(
(x-dx,y-dy),
2*dx,2*dy,
edgecolor="black",facecolor="None",
linestyle="--",linewidth=0.75,)
ax.add_patch(rect)
#绘制毗连补丁Patch
con=ConnectionPatch(
xyA=(x,y),coordsA=ax.transData,
xyB=(0,0.5),coordsB=sax.transAxes,
linestyle="--",linewidth=0.75,patchA=rect,arrowstyle="-",)fig.add_artist(con)
GridSpec:指定子图将放置的网格的多少位置。必要设置网格的行数和列数。子图布局参数(比方,左,右等)可以选择性调解。
ConnectionPatch:用于在两点之间创建毗连线。
参数:
xyA:它是x-y图上也称为点A的毗连线的出发点。
xyB:它是x-y图上毗连线的出发点,也称为点B。
coordsA:A点的坐标。
coordsB:B点的坐标。
axesA:它是x-y图上毗连轴的出发点。
axesB:它是x-y图上毗连轴的尽头。
arrowstyle:用于设置毗连箭头的样式。其默认范例为“-”。
arrow_transmuter:用于忽略毗连线。
connectionstyle:它形貌了posA和posB的毗连方式。它可以是ConnectionStyle类的实例,也可以是connectionstyle名称的字符串,它具有可选的逗号分隔属性。
connector:通常忽略它,并决定忽略哪个毗连器。
patchA:用于在A点添加补丁。
patchB:用于在B点添加补丁
shrinkA:用于在A点紧缩毗连器。
shrinkB:用于在B点紧缩毗连器。
mutation_scale:箭头样式的属性(比方head_length)的缩放比例值。
mutation_aspect:变异前,矩形的高度将被该值挤压,变异框将被其倒数拉伸。
clip_on:设置艺术家是否利用剪辑。
dpi_cor:dpi_cor当前用于linewidth-related事物和紧缩因子。突变规模受此影响。
参考资料
[1]latex-text-box:https://github.com/rougier/scientific-visualization-book/blob/master/code/ornaments/latex-text-box.py
[2]ScientificVisualisation-PythonMatplotlib
【声明】本文版权归原作者全部,内容为作者个人观点,转载目标在于转达更多信息,如涉及作品内容、版权等题目,可接洽本站删除,谢谢。
我要评论