You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

本地Streamlit应用中Plotly仪表盘图表异常渲染问题

解决Streamlit中Plotly仪表盘图表残留渲染问题

问题现象

  • 本地部署的Streamlit应用里,勾选「MTR」复选框切换到仪表盘页面后,取消勾选返回默认页面时,本该无图表的区域会出现3个透明的仪表盘图表。
  • 图表呈非预期的透明状态,属于页面切换后的组件渲染残留问题。

复现代码

import streamlit as st
import plotly.graph_objects as go

st.set_page_config(page_title='example', layout='wide')
colcheck1, colcheck2, colcheck3 = st.columns([1,1,4])

with colcheck1:
    mt = st.checkbox('MT')

with colcheck2:
    mtr = st.checkbox('MTR')


def mtr_page():
    col1, col2 = st.columns([3,10])


    with col1:
        fig = gauge_3()
        st.plotly_chart(fig)
        fig = gauge_3()
        st.plotly_chart(fig)

def gauge_creation(fig, value,title,domain):
    if value >= 90:
        color = 'green'
    elif value >=60:
        color = 'yellow'
    else:
        color = 'red'

    fig.add_trace(go.Indicator(
        mode='gauge+number',
        value = value,
        title=title,
        domain=domain,
        number={'suffix':'%'},
        gauge={
            'axis':{'range':[0,100],'tickwidth':1, 'showticklabels':False},
            'bar': {'color':color},
            'borderwidth':1
        }
    ))
    return fig

def gauge_3():
    fig = go.Figure()
    gauge_creation(fig,92,'30day',{'row':0, 'column':1})
    gauge_creation(fig,92,'90day',{'row':0, 'column':2})
    gauge_creation(fig,92,'1year',{'row':0, 'column':3})

    fig.add_annotation(dict(font=dict(color='white',size=15),
                            x=0,
                            y=.12,
                            showarrow=False,
                            text='Name',
                            xref='paper',
                            yref='paper'))
    fig.update_layout(
        grid = {'rows':1, 'columns':4, 'pattern':'independent'},
        width = 500,
        height = 100,
        margin = {'t':50, 'b':10, 'r':26, 'l': 18}
    )
    return fig

def test_blank():
    col1, col2 = st.columns([1,2])
    with col1:
        st.write('hi')

if mtr == False and mt == False:
    test_blank()

if mtr:
    mtr_page()

原因分析

Streamlit动态切换页面内容时,对于Plotly这类第三方图表组件的DOM元素回收存在不完全的情况。尤其是使用st.columns嵌套渲染图表时,旧组件的状态没有被彻底重置,导致切换回空白页面后,残留的透明图表DOM没有被清理。

解决方案

方法1:用会话状态精准控制页面渲染

通过st.session_state跟踪页面状态,确保切换时强制刷新内容,避免旧组件残留:

import streamlit as st
import plotly.graph_objects as go

st.set_page_config(page_title='example', layout='wide')

# 初始化会话状态,记录当前页面
if 'current_page' not in st.session_state:
    st.session_state.current_page = 'blank'

colcheck1, colcheck2, colcheck3 = st.columns([1,1,4])

with colcheck1:
    mt = st.checkbox('MT', on_change=lambda: st.session_state.update(current_page='mt' if mt else 'blank'))

with colcheck2:
    mtr = st.checkbox('MTR', on_change=lambda: st.session_state.update(current_page='mtr' if mtr else 'blank'))

# 原函数gauge_creation、gauge_3、mtr_page、test_blank保持不变

# 根据会话状态渲染对应页面
match st.session_state.current_page:
    case 'blank':
        test_blank()
    case 'mtr':
        mtr_page()

方法2:用占位符动态替换页面内容

使用st.empty()创建全局内容容器,切换页面时用新内容完全覆盖旧内容,确保旧图表被彻底移除:

import streamlit as st
import plotly.graph_objects as go

st.set_page_config(page_title='example', layout='wide')

# 创建全局内容占位符
content_container = st.empty()

colcheck1, colcheck2, colcheck3 = st.columns([1,1,4])

with colcheck1:
    mt = st.checkbox('MT')

with colcheck2:
    mtr = st.checkbox('MTR')

def mtr_page():
    with content_container.container():
        col1, col2 = st.columns([3,10])
        with col1:
            fig = gauge_3()
            st.plotly_chart(fig)
            fig = gauge_3()
            st.plotly_chart(fig)

def test_blank():
    with content_container.container():
        col1, col2 = st.columns([1,2])
        with col1:
            st.write('hi')

# 原函数gauge_creation、gauge_3保持不变

# 页面渲染逻辑
if mtr:
    mtr_page()
elif not mt and not mtr:
    test_blank()

方法3:优化Plotly图表布局配置

修改图表的背景色设置,避免透明残留问题,同时确保布局尺寸匹配容器:

def gauge_3():
    fig = go.Figure()
    gauge_creation(fig,92,'30day',{'row':0, 'column':1})
    gauge_creation(fig,92,'90day',{'row':0, 'column':2})
    gauge_creation(fig,92,'1year',{'row':0, 'column':3})

    fig.add_annotation(dict(font=dict(color='white',size=15),
                            x=0,
                            y=.12,
                            showarrow=False,
                            text='Name',
                            xref='paper',
                            yref='paper'))
    fig.update_layout(
        grid = {'rows':1, 'columns':4, 'pattern':'independent'},
        width = 500,
        height = 100,
        margin = {'t':50, 'b':10, 'r':26, 'l': 18},
        # 设置背景色与页面一致,避免透明残留
        paper_bgcolor=st.get_option('theme.backgroundColor'),
        plot_bgcolor=st.get_option('theme.backgroundColor')
    )
    return fig

内容的提问来源于stack exchange,提问作者Jason

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 20:35:22