有没有一种方法可以在每一帧动态更改 Plotly 动画的坐标轴刻度?

5

我有一个动态的Plotly散点图,通常在0-0.5范围内绘制xy坐标,并以日期/时间为帧关键字。有时候,我需要处理异常数据点,它们会远远超出这个范围。我希望图表能够动态缩放,使得数据点不会丢失。这是否可能?

def draw(x1,y1,timestamp):

    d = {
        "x1": x1_trim,
        "y1": y1_trim,
        "time": time_trim
    }
    
    df = pd.DataFrame(d)
  
    fig = px.scatter(df, x="x1", y="y1", animation_frame="time")
    fig.update_yaxes(autorange=True)
    fig.update_xaxes(autorange=True)
    fig.show()

我尝试使用update_x/yaxes和自动范围,但似乎无法工作。


每个帧都可以有自己的布局,https://plotly.com/python-api-reference/generated/plotly.graph_objects.Figure.html 查看 frames 定义。 - Rob Raymond
2个回答

3
正如评论中指出的那样,有一种方法可以更改每一帧的Plotly动画轴尺度。问题在于如何使其更加动态。但如果我们可以说你已经进行了一些计算,可以知道您想要调整哪些帧的范围,那么结合像yranges = {2002:[0, 200]}这样的字典和对帧的for循环应该就能解决问题。我们以px.data.gapminder数据集的子集为例。假设您想要调整以下图形中显示年份为2002的帧的y轴范围:

enter image description here

那么您可以包含以下代码片段,并获得如下所示的year = 2002的图形:

yranges = {2002:[0, 200]}
for f in fig.frames:
    if int(f.name) in yranges.keys():
        f.layout.update(yaxis_range = yranges[int(f.name)])

输入图片说明

完整代码:

import plotly.express as px
df = px.data.gapminder()
df = df[(df['continent'] == 'Asia') & (df['year'].isin([1997, 2002, 2007]))]

scales = [2002]

fig = px.scatter(df, x="gdpPercap", y="lifeExp", animation_frame="year", animation_group="country",
           size="pop", color="continent", hover_name="country",
           log_x=True, size_max=55, range_x=[100,100000], range_y=[25,90])

yranges = {2002:[0, 200]}

for f in fig.frames:
    if int(f.name) in yranges.keys():
        f.layout.update(yaxis_range = yranges[int(f.name)])

fig.show()

1
很好,我们得出了非常相似的解决方案。 - Rob Raymond
@RobRaymond 是的,当然做到了! - vestland

3
  • 每个帧都可以有自己的布局。
  • 构建图形后,循环遍历帧并定义x和y轴的range
  • 下面是代码:
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go

df = pd.DataFrame(
    {
        "time": np.tile(pd.date_range("1-jan-2021", freq="1H", periods=12), 10),
        "x": np.random.uniform(1, 4, 120),
        "y": np.random.uniform(2, 5, 120),
    }
)
fig = px.scatter(df, x="x", y="y", animation_frame=df["time"].dt.strftime("%H:%M"))

go.Figure(
    data=fig.data,
    frames=[
        fr.update(
            layout={
                "xaxis": {"range": [min(fr.data[0].x) - 0.1, max(fr.data[0].x) + 0.1]},
                "yaxis": {"range": [min(fr.data[0].y) - 0.1, max(fr.data[0].y) + 0.1]},
            }
        )
        for fr in fig.frames
    ],
    layout=fig.layout,
)

这看起来很有前途,但当我测试这段代码时,似乎plotly试图平滑过渡到不同的范围,但结果却非常糟糕,导致很多卡顿和跳跃的无意义动作。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接