Problem with functions in st.cache_data

To make my app smoother, i’m trying to cache all my plotly charts.
Each chart has a function that stores its selection.

I’m passing the function with an underscore so it will not be used for caching.
Here’s the code. I’m using streamlit 1.36.0

st.session_state.setdefault('aux_chart', None)
st.session_state.setdefault('aux_chart2', None)
def click_graf_chart():
    st.session_state.aux_chart = [point['y'] for point in st.session_state['chart1']['selection']['points']]
    if st.session_state.aux_chart:
        c1_values = ','.join(f'"{value}"' for value in st.session_state.aux_chart)
        c1_filtro = f'serv3 in [{c1_values}]'
        st.session_state.aux_chart = c1_filtro


def click_graf_chart_2():
    st.session_state.aux_chart2 = [point['y'] for point in st.session_state['chart2']['selection']['points']]
    if st.session_state.aux_chart2:
        c2_values = ','.join(f'"{value}"' for value in st.session_state.aux_chart2)
        c2_filtro = f'serv3 in [{c2_values} & status == "Aguardando" & justificativa == "Retorno do cliente"]'
        st.session_state.aux_chart2 = c2_filtro

@st.cache_data(ttl='30m')
def carregar_dados():
    aux = consultar_tickets_ex()
    ext = campos_extras()

    tickets = pd.merge(aux, ext, how='left', on='ticket')

    _aux = tickets[tickets['status'].isin(['Aguardando', 'Em atendimento', 'Novo', 'Parado'])]

    return _aux

dados_aux = carregar_dados()

filtros = [var for var in [st.session_state.aux_chart,st.session_state.aux_responsavel,st.session_state.aux_urgencia] if var]
filtro_combinado = ' and '.join(filtros)

dados = dados_aux

if filtro_combinado:
    dados = dados.query(filtro_combinado)


contagem_tickets_geral = dados['ticket'].nunique()
contagem_tickets_geral = locale.format_string('%d', contagem_tickets_geral, grouping=True)

graf_total_tickets_aux = dados.groupby('serv3')['ticket'].count().reset_index()
graf_total_tickets_aux = graf_total_tickets_aux.drop(graf_total_tickets_aux[graf_total_tickets_aux['ticket'] == 0].index)
graf_total_tickets_aux = graf_total_tickets_aux.sort_values(by='ticket', ascending=False)

contagem_tickets_aguard_aux = dados.loc[(dados['status'] == 'Aguardando') & (dados['justificativa'] == 'Retorno do cliente')].groupby('serv3')['ticket'].count().reset_index()
aguardando_cli = contagem_tickets_aguard_aux['ticket'].nunique()
aguardando_cli = locale.format_string('%d', aguardando_cli, grouping=True)


@st.cache_data(ttl='5h')
def grafico_funil_serv(df, chart_key, _func):
    colors = {
        'Power BI/Orion': '#262626',
        'Sistemas': '#ACBFA4',
        'T.I Infraestrutura': '#E2E8CE',
        'VX 360': '#AFCBFF',
        'Projetos': '#0091AD'
    }
    graf = px.funnel(df,
                                x='ticket',
                                y='serv3',
                                height=300
                                )
    graf.update_layout(showlegend=False, xaxis_title=None, yaxis_title=None)
    graf.update_traces(textinfo='value+percent total')
    graf.update_traces(marker_color=df['serv3'].map(colors))
    graf.update_layout(xaxis=dict(showticklabels=False))
    st.plotly_chart(graf, use_container_width=True, key=chart_key, selection_mode='points', on_select=_func)


col1, col2 = st.columns(2,gap='small')
with col1:
    st.metric(label='Qtd Tickets', value=contagem_tickets_geral)
with col2:
    st.metric(label='Ag. Retorno *(do cliente)*', value=aguardando_cli)

grafico_funil_serv(graf_total_tickets_aux, 'chart1', click_graf_chart)

But i’m getting the error:

That is a warning, not an error.

Yes, sure, it’s a warning.

But, i can’t cache the “action” of ploting the chart (st.plotly_chart) ?

I don’t want streamlit to recreate the chart that all the time.

Is there a way to ignore this warning ? I thought that using hash would solve.

No, just as you can’t cache the action of displaying some text or a picture. That is what the warning is telling you.

However, you can cache a plotly Figure object, the same as you would cache the text or the picture. That may or may not have a significant impact on performance, in case you are having a performance issue (are you having one, btw?) Unfortunately your code has too many undefined names so I cannot test.

You don’t need to recreate the Figure on each rerun, you can have it stored in cache or in session state. But you do need to call plotly_chart on each rerun if you want the chart displayed.

Setting client.showErrorDetails to false in the configuration might achieve that, but I don’t think the application would work as you want.

Hello Goyo,

I just want to confirm: can we use the @st_cache_data decorator to cache our Plotly charts? Or are the charts actually cached by session state?

I am currently facing a similar issue as the author. I checked the following website which states, “Decorator to cache functions that return data (e.g., dataframe transforms, database queries, ML inference).” Plotly plots are not listed among the datatypes that can use st_cache_data.

I use Streamlit 1.23.1

Depends on what exactly you call “Plotly charts”. You can use it to cache almost any python object.

No.

Would you say that “Plotly plots” are data? If you are unsure, you can still try.