python用plotly实现绘制局部放大图

 更新时间:2022年02月13日 11:17:56   作者:Eloik  
大家好,本篇文章主要讲的是python用plotly实现绘制局部放大图,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下

最终效果展示

在这里插入图片描述

实现思路

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

导入库

import plotly.io as pio
import plotly.graph_objects as go
import pandas as pd
import numpy as np

# 设置plotly默认主题,白色主题
pio.templates.default = 'plotly_white'

随机生成一些数据

# x坐标
x = np.arange(1, 1001)

# 生成y轴数据,并添加随机波动
y1 = np.log(x)
indexs = np.random.randint(0, 1000, 800)
for index in indexs:
    y1[index] += np.random.rand() - 0.5
y1 = y1 + 0.2

y2 = np.log(x)
indexs = np.random.randint(0, 1000, 800)
for index in indexs:
    y2[index] += np.random.rand() - 0.5

y3 = np.log(x)
indexs = np.random.randint(0, 1000, 800)
for index in indexs:
    y3[index] += np.random.rand() - 0.5
y3 = y3 - 0.2

封装绘图代码

class LocalZoomPlot:
    def __init__(self, x, y, colors, x_range, scale=0.):
        """
        :param x: x轴坐标,列表类型
        :param y: y轴坐标,二维列表类型,例如 [y1, y2, y3]
        :param colors: 每个曲线的颜色,必须与 len(y) 相等
        :param x_range: 需要缩放区域的x轴范围
        :param scale: 详见 getRangeMinMaxValue 函数
        """
        self.x = x
        self.y = y
        self.colors = colors
        self.x_range = x_range
        self.y_range = self.getRangeMinMaxValue(x_range, scale)
    
    def getRangeMinMaxValue(self, x_range, scale=0.):
        """
        获取指定x轴范围内,所有y数据的最大值和最小值

        :param x_range: 期望局部放大的x轴范围
        :param scale: 将最大值和最小值向两侧延伸一定距离
        """
        min_value = np.min([np.min(arr[x_range[0]:x_range[1]]) for arr in self.y])
        max_value = np.max([np.max(arr[x_range[0]:x_range[1]]) for arr in self.y])
        # 按一定比例缩放
        min_value = min_value - (max_value - min_value) * scale
        max_value = max_value + (max_value - min_value) * scale
        # 返回缩放后的结果
        return min_value, max_value
    
    def originPlot(self, fig, **kwargs):
        """
        根据 y 数据绘制初始折线图

        :param fig: go.Figure实例
        """
        fig.add_traces([
            go.Scatter(x=self.x, y=arr, opacity=0.7, marker_color=self.colors[i], **kwargs)
            for i, arr in enumerate(self.y)
        ]) 
        return fig

    def insetPlot(self, fig, inset_axes):
        """
        在原始图像上插入嵌入图

        :param fig: go.Figure对象实例
        :param inset_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)
        )
        return fig
    
    def rectOriginArea(self, fig):
        """
        将放大的区域框起来

        :param fig: 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
        ))
        return fig

    def addConnectLine(self, fig, area_point_num, point):
        """
        从放大区域指定点连线

        :param fig: go.Figure实例
        :param area_point_num: 放大区域的锚点,例如:(0, 0)表示放大区域的左下角坐标,(0, 1)表示左上角坐标,
          (1, 0)表示右下角坐标,(1, 1)表示右上角坐标,只能取这四种情况
        :param point: 要进行连线的另一个点,通常位于嵌入图附近,根据美观程度自行指定
        """
        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},
        )
        return fig

开始绘制

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实现绘制局部放大图的文章就介绍到这了,更多相关python plotly绘制局部放大图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 如何使用pycharm连接Databricks的步骤详解

    如何使用pycharm连接Databricks的步骤详解

    这篇文章主要介绍了如何使用pycharm连接Databricks,本文分步骤给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • python如何拆分含有多种分隔符的字符串

    python如何拆分含有多种分隔符的字符串

    这篇文章主要为大家详细介绍了python如何拆分含有多种分隔符的字符串,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • Python 调用 ES、Solr、Phoenix的示例代码

    Python 调用 ES、Solr、Phoenix的示例代码

    这篇文章主要介绍了Python 调用 ES、Solr、Phoenix的示例代码,帮助大家更好的理解和学习python,感兴趣的朋友可以了解下
    2020-11-11
  • python输入多行的方法总结

    python输入多行的方法总结

    Python中的Input()函数在输入时,遇到回车符,那么一次输入就结束了,这不能满足输入多行文本并且行数也不确定的情形,当然输入空行也是允许的,本文给大家总结了python输入多行的方法,需要的朋友可以参考下
    2024-04-04
  • python如何读取bin文件并下发串口

    python如何读取bin文件并下发串口

    这篇文章主要介绍了python如何读取bin文件并下发串口,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • Python字符串hashlib加密模块使用案例

    Python字符串hashlib加密模块使用案例

    这篇文章主要介绍了Python字符串hashlib加密模块使用案例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • python 编码中为什么要写类型注解?

    python 编码中为什么要写类型注解?

    这篇文章主要介绍了python 编码中为什么要写类型注解,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下
    2021-03-03
  • python正则分组的应用

    python正则分组的应用

    组是通过 "(" 和 ")" 元字符来标识的。 "(" 和 ")" 有很多在数学表达式中相同的意思;它们一起把在它们里面的表达式组成一组
    2013-11-11
  • 使用Python实现合并多个Excel文件

    使用Python实现合并多个Excel文件

    合并Excel可以将多个文件中的数据合并到一个文件中,这样可以帮助我们更好地汇总和管理数据,本文主要介绍了如何使用第三方Python库 Spire.XLS for Python 实现以上两种合并Excel文件的需求,有需要的可以了解下
    2023-12-12
  • python安装oracle扩展及数据库连接方法

    python安装oracle扩展及数据库连接方法

    这篇文章主要介绍了python安装oracle扩展及数据库连接方法,较为详细的分析了Python下载oracle扩展及Windows、Linux环境下的安装步骤、操作技巧及注意事项,需要的朋友可以参考下
    2017-02-02

最新评论