Python-matplotlib-注解与图例
Matplotlib 注解与图例精确的注解和清晰的图例让图表会说话。本章覆盖annotate、text、legend等各种标注方法。️ax.annotate()— 精确注解 ⭐基本用法importmatplotlib.pyplotaspltimportnumpyasnp fig,axplt.subplots(figsize(10,6))xnp.linspace(0,10,100)ynp.sin(x)ax.plot(x,y,b-,linewidth2)# 基本注解ax.annotate(local max,# 文本xy(1.57,1.0),# 被标注的点数据坐标xytext(3,1.2),# 文本位置数据坐标arrowpropsdict(arrowstyle-,colorred),fontsize12,colorred)# 偏移量方式推荐ax.annotate(peak,xy(1.57,1.0),xytext(50,30),# 文本偏移点pointstextcoordsoffset points,# 文本坐标系统arrowpropsdict(arrowstyle-,connectionstylearc3,rad.4),fontsize12,bboxdict(boxstyleround,pad0.3,facecolorlightyellow,edgecolorgray,alpha0.8))箭头样式# arrowstyle 选项arrowstyles[-,-,-[,-,-,|-|,fancy,simple,wedge]# connectionstyle 选项# arc3,radangle 弧线rad 控制弯曲# angle,angleAa,angleBb 指定出/入角度# angle3,angleAa,angleBb 类似但更平滑# bar,armAa,armBb 直转角fig,axesplt.subplots(3,3,figsize(12,10))forax,styleinzip(axes.flat,arrowstyles):ax.set(xlim(0,10),ylim(0,10))ax.annotate(,xy(7,5),xytext(3,5),arrowpropsdict(arrowstylestyle))ax.set_title(style,fontsize10)注解属性ax.annotate(text,xy(x,y),# 被标注点xytext(dx,dy),# 文本位置xycoordsdata,# xy 的坐标系统textcoordsoffset points,# xytext 的坐标系统hacenter,vacenter,# 文本对齐arrowpropsdict(arrowstyle-,# 箭头样式connectionstylearc3,rad0.3,# 连接样式colorblack,lw1.5,shrinkA5,# 箭头收缩不与数据点重叠shrinkB5,mutation_scale20,# 箭头头大小),bboxdict(# 文本框样式boxstyleround,pad0.5,facecoloryellow,edgecolorgray,alpha0.8),fontsize12,colorblack,weightbold,styleitalic# normal, italic, oblique)坐标系统坐标系统范围说明data数据范围默认使用数据坐标axes fraction(0,0)-(1,1)轴内相对位置figure fraction(0,0)-(1,1)图内相对位置offset pixels像素相对 xy 的像素偏移offset pointspoints相对 xy 的点的偏移ax.text()— 自由文本fig,axplt.subplots(figsize(10,6))# 基本文本ax.text(0.5,0.5,Center Text,transformax.transAxes,# 使用轴坐标hacenter,vacenter,fontsize16,fontweightbold)# 在图中添加水印ax.text(0.5,0.5,DRAFT,transformax.transAxes,hacenter,vacenter,fontsize72,colorgray,alpha0.15,rotation30)# 数据坐标文本ax.text(3,0.5,Annotation at x3,fontsize12)文本框ax.text(0.05,0.95,Key Insights:\n• Sales up 23%\n• Costs down 5%\n• Profit margin: 18%,transformax.transAxes,verticalalignmenttop,fontsize11,bboxdict(boxstyleround,pad0.5,facecolorlightblue,edgecolornavy,alpha0.8))ax.legend()— 图例基本用法fig,axplt.subplots(figsize(10,6))xnp.linspace(0,10,100)ax.plot(x,np.sin(x),labelsin(x))ax.plot(x,np.cos(x),labelcos(x))ax.plot(x,np.sin(x)*np.exp(-0.1*x),labeldamped sin)# 自动从 label 生成图例ax.legend()# 自定义ax.legend(locupper right,# 位置fontsize11,frameonTrue,# 是否显示边框framealpha0.8,# 边框透明度facecolorlightgray,# 背景色edgecolorblack,# 边框色ncol2,# 列数titleFunctions,title_fontsize12,shadowTrue# 阴影)loc位置参数# 字符串方式推荐# best (默认), upper right, upper left, lower left, lower right# right, center left, center right, lower center, upper center, center# 坐标方式: loc(x, y) # 图例左下角在轴坐标系中的位置ax.legend(locupper right)ax.legend(loc(0.02,0.98))ax.legend(loclower left,bbox_to_anchor(1,1))# 放在图外右上ax.legend(locupper center,bbox_to_anchor(0.5,-0.15),ncol4)# 放在图下选择性图例# 手动控制哪些 artist 出现在图例中line1,ax.plot(x,y1,colorr)line2,ax.plot(x,y2,colorb)line3,ax.plot(x,y3,colorg)# 只包含 line1 和 line3ax.legend([line1,line3],[Series A,Series C])# 标签也可直接指定ax.legend([line1,line2,line3],[Important,Minor,Noise],locupper left)修改已有图例legax.legend()leg.set_title(New Title)leg.set_alpha(0.5)leg.get_frame().set_linewidth(0)# 去掉边框# 修改图例中的文字fortextinleg.get_texts():text.set_fontsize(12)text.set_weight(bold)图例外放# 放在图的右侧fig,axplt.subplots(figsize(10,6))ax.plot(x,y1,labelLine 1)ax.plot(x,y2,labelLine 2)ax.legend(bbox_to_anchor(1.05,1),locupper left)fig.tight_layout()# 自动调整以容纳图例# 下方横排ax.legend(bbox_to_anchor(0.5,-0.15),locupper center,ncol4,frameonFalse)⬆️ 箭头与指示线独立箭头# ax.arrow: 简单箭头ax.arrow(0,0,1,1,head_width0.1,head_length0.15,fcred,ecred,width0.03)# FancyArrowPatch: 更灵活的箭头frommatplotlib.patchesimportFancyArrowPatch arrowFancyArrowPatch((0,0),(3,2),arrowstylefancy,colorblue,linewidth2,mutation_scale20)ax.add_patch(arrow)连接线 (ConnectionPatch)frommatplotlib.patchesimportConnectionPatch# 连接两个不同 Axes 的点fig,(ax1,ax2)plt.subplots(1,2,figsize(12,5))ax1.scatter([1],[5],s100,colorred)ax2.scatter([3],[8],s100,colorred)# 从 ax1 的点到 ax2 的点conConnectionPatch(xyA(1,5),xyB(3,8),coordsAdata,coordsBdata,axesAax1,axesBax2,arrowstyle-,linewidth2,colorgray)fig.add_artist(con) 表格与文本ax.table()— 添加表格fig,axplt.subplots(figsize(10,5))ax.plot(x,np.sin(x))# 在图中嵌入表格data[[123,456,789],[234,567,890],[345,678,901]]tableax.table(cellTextdata,colLabels[Q1,Q2,Q3],rowLabels[Product A,Product B,Product C],locbottom,bbox[0.0,-0.5,1.0,0.3]# [left, bottom, width, height])# table.auto_set_font_size(False)# table.set_fontsize(10)# table.scale(1, 1.5)fig.text()— 图级文本# 添加图级标题/脚注fig.text(0.5,0.02,Source: Company Reports 2024,hacenter,fontsize10,colorgray,styleitalic)fig.text(0.5,0.95,Figure 1: Revenue Analysis,hacenter,fontsize14,fontweightbold) 实战: 专业标注fig,axplt.subplots(figsize(12,7))# 数据xnp.linspace(0,12,200)ynp.sin(x)*np.exp(-0.1*x)ax.plot(x,y,b-,linewidth2,labelSignal)# 标注极值点peaks_x[1.5,7.5]peaks_y[np.sin(xp)*np.exp(-0.1*xp)forxpinpeaks_x]forpx,pyinzip(peaks_x,peaks_y):ax.annotate(fPeak ({px:.1f},{py:.3f}),xy(px,py),xytext(px1.5,py0.15),fontsize10,arrowpropsdict(arrowstyle-,colordarkred),bboxdict(boxstyleround,facecolorwheat,alpha0.8))# 高亮区域ax.axvspan(4,6,alpha0.1,colorred,labelAnomaly Zone)ax.axhline(0,colorgray,linestyle--,linewidth0.5)# 图例ax.legend(locupper right,frameonTrue,fontsize11)# 标签ax.set_xlabel(Time (s),fontsize13)ax.set_ylabel(Amplitude,fontsize13)ax.set_title(Damped Oscillation with Annotations,fontsize15)# 文本框ax.text(0.02,0.95,N 200\ndt 0.06s,transformax.transAxes,vatop,bboxdict(boxstyleround,facecolorlightgray),fontsize10)fig.tight_layout()[[matplotlib3-总览|← 返回总览]]