3D Surface 日期轴在 Shiny for Python 中未正确渲染

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

我在用Python闪亮的表面图正确渲染轴日期时遇到一些问题。 特别是,日期类型的轴呈现为浮点数。

shiny Playground 中找到一个示例。

请注意,如果我在 python闪亮之外使用Fig.show()渲染图形(即x轴渲染为日期而不是浮点数),则相同的代码可以工作。

我已经尝试将图形的布局明确地转换为

fig.update_layout(
            scene=dict(
                xaxis=dict(
                    type="date",
                    tickformat='%Y'
                )
            )

但我得到了最糟糕的结果(图根本没有渲染)。

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

@render_widget
替换为
express.render.ui
,并将
return fig
替换为
return ui.HTML(fig.to_html())
(请参阅
express.ui.HTML
plotly.io.to_html
)。

enter image description here

游乐场链接

import plotly.graph_objects as go
import pandas as pd
import numpy as np
from shiny.express import render, ui

def plotSurface(plot_dfs: list, names: list, title: str, **kwargs):
    """helper function to plot multiple surface with ESM color themes.

    Args:
        plot_dfs (list): list of dataframes containing the matrix. index of each df is datetime format and columns are maturities
        names (list): list of names for the surfaces in plot_dfs
        title (str): title of the plot

    Raises:
        TypeError: _description_
        TypeError: _description_
        ValueError: _description_

    Returns:
        Figure: plotly figure
    """
    for i, plot_df in enumerate(plot_dfs):
        if not isinstance(plot_df.index, pd.core.indexes.datetimes.DatetimeIndex):
            raise TypeError(f"plot_df number {i} in plot_dfs should have an index of type datetime but got {type(plot_df.index)}")
    if not (isinstance(plot_dfs, list) and isinstance(names, list)):
        raise TypeError(f"both plot_dfs and names should be list. Instead got {type(plot_dfs), {type(names)}}")
    if len(plot_dfs) != len(names):
        raise ValueError(f"plot_dfs and names should have the same length but got {len(plot_dfs)} != {len(names)}")
    
    fig = go.Figure()

    # stack surfaces. The last one will overwrite the first one when values are equal
    for i, (plot_df, name) in enumerate(zip(plot_dfs, names)):
        X, Y = np.meshgrid(plot_df.index, plot_df.columns)
        Z = plot_df.values.T
        fig.add_trace(go.Surface(z=Z, x=X, y=Y, name=name, showscale=False, showlegend=True, opacity=0.9))
    
    # Update layout for better visualization and custom template
    fig.update_layout(
        title=title,
        title_x=0.5,
        scene=dict(
            xaxis_title='Date',
            yaxis_title='Maturity',
            zaxis_title='Value',
        ),
        margin=dict(l=30, r=30, b=30, t=50),
        # template=esm_theme,
        legend=dict(title="Legend"),
    )

    return fig


@render.ui
def plot_1():
    plot_dfs = [
        pd.DataFrame(
            index = pd.to_datetime([f"{y}/01/01" for y in range(2020, 2100)]),
            columns = ["3m", "6m", "9m"] + [f"{y}Y" for y in range(1,31)],
            data = 1
        ) 
    ]

    fig = plotSurface(plot_dfs, names=["t"], title=" ")
    return ui.HTML(fig.to_html())
© www.soinside.com 2019 - 2024. All rights reserved.