有没有办法动态改变每帧的绘图动画轴比例?

Is there a way to dynamically change a plotly animation axis scale per frame?

我有一个动画绘图散点图,它绘制的 x、y 坐标通常在 0-0.5 范围内,date/time 是帧键。然而,有时我将不得不处理超出此范围的异常数据点。我希望图表能够动态缩放,这样点就不会从屏幕上丢失。这可能吗?

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 和自动调整范围,但它似乎不起作用。

正如评论中所指出的,有一种方法可以改变每帧的绘图动画轴比例。问题仍然是如何 dynamic 做到这一点。但是如果我们可以说你已经做了一些计算让你知道你想调整哪些帧的范围,那么组合像 yranges = {2002:[0, 200]} 的字典和帧上的 for 循环应该做的伎俩。我们以数据集 px.data.gapminder 的一个子集为例。假设您想调整显示年份 2002 数据的框架的 yaxis 范围,如下图所示:

然后你可以包含以下代码片段,并得到下图 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()
  • 每一帧都可以有自己的布局
  • 构建图形后,循环帧并定义 x 和 y 轴 范围
  • 下面的代码
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,
)