PyShiny (Express) 中的动画绘图

问题描述 投票:0回答:1

我试图使用plotly 生成动画3D 散点图,并将其显示在我使用Shiny (Python) Express 创建的仪表板上。当在 jupyter 笔记本上检查动画绘图的代码时 - 它工作得很好,但我无法让动画在 Shiny 上运行。

该图表是交互式的 - 即工具提示显示数据,但单击“播放”时没有动画。

import io
from pathlib import Path
from shiny import reactive
from shiny.express import input, ui, render
from shiny.types import FileInfo
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
from shinywidgets import render_widget
import asyncio

ui.page_opts(
    title="Visualisation",
    fillable=True,
    id="page",
    )

with ui.card(full_screen=True):
    @render_widget
    def coordinate_space():
        try:
            with ui.Progress(min=1, max=5) as p:
                data = {
                    'X': [1, 2, 3, 4, 5],
                    'Y': [5, 4, 3, 2, 1],
                    'Z': [2, 3, 4, 5, 6],
                    'FZ_new': [10, 20, 30, 40, 50],
                    'FZ': [5, 10, 15, 20, 25]
                }

                scaled_coordinate_system = pd.DataFrame(data)

                p.set(2, message="Data loaded, preparing plot...")


                fig = px.scatter_3d(scaled_coordinate_system, x='X', y='Y', z='Z',
                    size='FZ_new', color='FZ_new', opacity=0.7)

                fig1 = go.Figure(fig)
                p.set(3, message="Adding traces to the plot...")

                    
                frames = [
                    go.Frame(data=[go.Scatter3d(
                        x=scaled_coordinate_system['X'], 
                        y=scaled_coordinate_system['Y'], 
                        z=scaled_coordinate_system['Z'], 
                        mode='markers', 
                        marker=dict(size=scaled_coordinate_system['FZ_new'] * 10, color="Red"),
                        opacity=0.9,
                        name='Frame 1',
                        
                    )]),
                    go.Frame(data=[go.Scatter3d(
                        x=scaled_coordinate_system['X'], 
                        y=scaled_coordinate_system['Y'], 
                        z=scaled_coordinate_system['Z'], 
                        mode='markers', 
                        marker=dict(size=scaled_coordinate_system['FZ'], color=scaled_coordinate_system['FZ']),
                        opacity=0.7,
                        name='Frame 2'
                    )])
                ]

                print("Frames")

                fig1.frames = frames

                p.set(4, message="Updating layout...")

                fig1.update_layout(
                    scene=dict(
                        xaxis_title='X AXIS',
                        yaxis_title='Y AXIS',
                        zaxis_title='Z AXIS'
                    ),
                    updatemenus=[dict(
                        type='buttons', 
                        direction = "down",
                        showactive=True, 
                        buttons=[
                            dict(
                                label='Play',
                                method='animate', 
                                args=[None, dict(
                                    frame=dict(duration=500, redraw=True),
                                    fromcurrent=True, 
                                    transition=dict(duration=0)
                                )]
                            ),
                            dict(
                                label='Pause',
                                method='animate',
                                args=[[None], dict(
                                    frame=dict(duration=0, redraw=False),
                                    mode='immediate'
                                )]
                            )
                        ]
                    )]
                )

                fig1.update_layout(margin=dict(l=0, r=0, b=0, t=0))
                camera = dict(
                    eye=dict(x=2, y=2, z=0.5)
                )

                fig1.update_layout(scene_camera=camera)
                p.set(5, message="Rendering plot...")
                return fig1

        except Exception as e:
            ui.notification_show(f"{e}", duration=20, type="error")
            return None

上面是我的渲染绘图函数的代码。我在想动画渲染问题是否与异步函数有关,所以我将其更改为同步。我不知道该怎么办。

编辑:我的动画仅影响散点图中标记的大小。

有人可以帮我吗?

python-3.x plotly py-shiny
1个回答
0
投票

要渲染绘图,只需按如下所示更改这两行:
(1)

@render_widget
->
@render.ui

(2)
return fig1
->
return ui.HTML(fig1.to_html())

它会起作用的。如果您想知道为什么它不适用于

@render_widget
,那是因为它隐式地将
go.Figure()
转换为
go.FigureWidget()
并且
go.FigureWidget()
不支持
frames
。因此,解决方法是在 HTML 标记内渲染。

© www.soinside.com 2019 - 2024. All rights reserved.