这篇文章将为大家详细讲解有关python怎么用plotly实现绘制局部放大图,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

最终效果展示

实现思路

在绘图区域插入一个嵌入图,嵌入图与原图的绘画保持一致,通过限制嵌入图的x轴和y轴的显示范围,达到缩放的效果,并在原图上绘画一个矩形框,以凸显缩放的区域,最后通过两条直线凸显缩放关系。

导入库

importplotly.ioaspioimportplotly.graph_objectsasgoimportpandasaspdimportnumpyasnp#设置plotly默认主题,白色主题pio.templates.default='plotly_white'随机生成一些数据

#x坐标x=np.arange(1,1001)#生成y轴数据,并添加随机波动y1=np.log(x)indexs=np.random.randint(0,1000,800)forindexinindexs:y1[index]+=np.random.rand()-0.5y1=y1+0.2y2=np.log(x)indexs=np.random.randint(0,1000,800)forindexinindexs:y2[index]+=np.random.rand()-0.5y3=np.log(x)indexs=np.random.randint(0,1000,800)forindexinindexs:y3[index]+=np.random.rand()-0.5y3=y3-0.2封装绘图代码

classLocalZoomPlot:def__init__(self,x,y,colors,x_range,scale=0.):""":paramx:x轴坐标,列表类型:paramy:y轴坐标,二维列表类型,例如[y1,y2,y3]:paramcolors:每个曲线的颜色,必须与len(y)相等:paramx_range:需要缩放区域的x轴范围:paramscale:详见getRangeMinMaxValue函数"""self.x=xself.y=yself.colors=colorsself.x_range=x_rangeself.y_range=self.getRangeMinMaxValue(x_range,scale)defgetRangeMinMaxValue(self,x_range,scale=0.):"""获取指定x轴范围内,所有y数据的最大值和最小值:paramx_range:期望局部放大的x轴范围:paramscale:将最大值和最小值向两侧延伸一定距离"""min_value=np.min([np.min(arr[x_range[0]:x_range[1]])forarrinself.y])max_value=np.max([np.max(arr[x_range[0]:x_range[1]])forarrinself.y])#按一定比例缩放min_value=min_value-(max_value-min_value)*scalemax_value=max_value+(max_value-min_value)*scale#返回缩放后的结果returnmin_value,max_valuedeforiginPlot(self,fig,**kwargs):"""根据y数据绘制初始折线图:paramfig:go.Figure实例"""fig.add_traces([go.Scatter(x=self.x,y=arr,opacity=0.7,marker_color=self.colors[i],**kwargs)fori,arrinenumerate(self.y)])returnfigdefinsetPlot(self,fig,inset_axes):"""在原始图像上插入嵌入图:paramfig:go.Figure对象实例:paraminset_axes:嵌入图的位置和大小[左下角的x轴位置,左下角的y轴位置,宽度,高度]所有坐标都是绝对坐标(0~1之间)"""#使用创建子图中的嵌入图参数,创建一个嵌入图fig=fig.set_subplots(insets=[dict(type='xy',l=inset_axes[0],b=inset_axes[1],w=inset_axes[2],h=inset_axes[3],)])#嵌入图与原始图的绘画一致,需要指定xaxis和yaxis参数确保是在嵌入图上绘画的fig=self.originPlot(fig,xaxis='x2',yaxis='y2',showlegend=False)#将嵌入图的坐标轴范围限定在指定范围fig.update_layout(xaxis2=dict(range=self.x_range),yaxis2=dict(range=self.y_range))returnfigdefrectOriginArea(self,fig):"""将放大的区域框起来:paramfig:go.Figure实例"""fig.add_trace(go.Scatter(#从左上角开始,顺时针连线x=np.array(self.x_range)[[0,1,1,0,0]],y=np.array(self.y_range)[[1,1,0,0,1]],mode='lines',line={'color':'#737473','dash':'dash','width':3},showlegend=False))returnfigdefaddConnectLine(self,fig,area_point_num,point):"""从放大区域指定点连线:paramfig:go.Figure实例:paramarea_point_num:放大区域的锚点,例如:(0,0)表示放大区域的左下角坐标,(0,1)表示左上角坐标,(1,0)表示右下角坐标,(1,1)表示右上角坐标,只能取这四种情况:parampoint:要进行连线的另一个点,通常位于嵌入图附近,根据美观程度自行指定"""fig.add_shape(type='line',x0=self.x_range[area_point_num[0]],y0=self.y_range[area_point_num[1]],x1=point[0],y1=point[1],line={'color':'#737473','dash':'dash','width':1},)returnfig开始绘制

plot=LocalZoomPlot(x,[y1,y2,y3],['#f0bc94','#7fe2b3','#cba0e6'],(100,150),0.)fig=go.Figure()fig=plot.originPlot(fig)fig=plot.insetPlot(fig,(0.4,0.2,0.4,0.3))fig=plot.rectOriginArea(fig)fig=plot.addConnectLine(fig,(0,0),(420,-0.7))fig=plot.addConnectLine(fig,(1,1),(900,2.7))#额外对图片进行设置fig.update_layout(width=800,height=600,xaxis=dict(rangemode='tozero',showgrid=False,zeroline=False,),xaxis2=dict(showgrid=False,zeroline=False),)fig.show()

关于“python怎么用plotly实现绘制局部放大图”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。