Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Altair expressions examples not working #3707

Open
kgozman6159 opened this issue Dec 4, 2024 · 3 comments
Open

Altair expressions examples not working #3707

kgozman6159 opened this issue Dec 4, 2024 · 3 comments
Labels

Comments

@kgozman6159
Copy link

kgozman6159 commented Dec 4, 2024

What happened?

Hi! I was trying to reproduce the last two examples given in the Altair user guide for interactive expressions and they both give me errors when I try to render the charts. I am trying to render the charts within Streamlit, but I'm getting Altair param errors, so I think this is an Altair problem. I'm running the following code:

# ----------import necessary packages---------- #
import streamlit as st
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import altair as alt

from collections import OrderedDict
st.set_page_config(layout="wide")

from vega_datasets import data

cars = data.cars()
print(cars)


input_dropdown = alt.binding_select(options=['Europe', 'Japan', 'USA'], name='Origin ')
selection = alt.selection_point(fields=['Origin'], bind=input_dropdown, value='Europe')

title = alt.Title(alt.expr(f'"Cars from " + {selection.name}.Origin'))

chart1 = alt.Chart(cars, title=title).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
).add_params(
    selection
).transform_filter(
    selection
)

search_input = alt.param(
    value='',
    bind=alt.binding(
        input='search',
        placeholder="Car model",
        name='Search ',
    )
)
search_matches = alt.expr.test(alt.expr.regexp(search_input, "i"), alt.datum.Name)

chart2 = alt.Chart(cars).mark_point(size=60).encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    tooltip='Name:N',
    opacity=alt.when(search_matches).then(alt.value(1)).otherwise(alt.value(0.05)),
).add_params(search_input)


st.altair_chart(chart1, use_container_width=True)
st.altair_chart(chart2, use_container_width=True)

and I get the same two errors Error: Unrecognized signal name: "param_XXX" where XXX is a number.

What would you like to happen instead?

Is this a known issue? Or am I doing something wrong? I'd like for this to render the two charts with the selections and searching enabled. Thanks!

Which version of Altair are you using?

I'm using altair 5.4.1 and python 3.11.0.

@kgozman6159 kgozman6159 added the bug label Dec 4, 2024
@kgozman6159 kgozman6159 changed the title Atlair expressions examples not working Altair expressions examples not working Dec 4, 2024
@joelostblom
Copy link
Contributor

Could you try without the streamlit parts in the code? It seems to be working fine for me.

@kgozman6159
Copy link
Author

Ah ok, it works fine if I just copy and paste it into a Jupyter notebook. The weirdness does indeed arise from putting it into Streamlit, and the behavior is unexpected--if I launch the Streamlit app for the first time, the code runs just fine and I'm able to do the search, etc. but as soon as I go to the code, change one thing (even something small like the opacity default from 1 to 0.7), and rerun/reload the Streamlit page, it defaults to the Error: Unrecognized signal name: "param_X" error. The only way for it to function again is if I quit the Streamlit server (control+c) and restart it again...I'm guessing there's something going on with how Altair is reacting to the way Streamlit reruns an application every time its changed?

Instead of modifying the code, I can also cause the error by creating a Streamlit button (that does nothing) above the chart, and when I click it (making Streamlit rerun the entire application), it causes the error to show up again and I have to completely restart the Streamlit server to make it function again.

@mattijn
Copy link
Contributor

mattijn commented Dec 4, 2024

Thanks for raising! Related issues are #3416 and #3589.

We should stabilize parameter definitions within Altair so chart definitions can be safely re-run.

Example:

import altair as alt
from vega_datasets import data

def chart_with_param():
    cars = data.cars()
    op_var = alt.param(value=0.1)

    chart = alt.Chart(cars).mark_circle(opacity=op_var).encode(
        x='Horsepower:Q',
        y='Miles_per_Gallon:Q',
        color='Origin:N'
    ).add_params(
        op_var
    )
    return chart.to_dict()
# run 1
chart_as_dict = chart_with_param()
chart_as_dict['data'], chart_as_dict['params']
({'name': 'data-583e73726c1545c56c203344161a975c'},
 [{'name': 'param_1', 'value': 0.1}])
# run 2
chart_as_dict = chart_with_param()
chart_as_dict['data'], chart_as_dict['params']
({'name': 'data-583e73726c1545c56c203344161a975c'},
 [{'name': 'param_2', 'value': 0.1}])

As you can see, the data reference is staying equal when re-run (using hashing, see here), but the parameter definitions goes from param_1 to param_2 (using a counter, see here). Streamlit tries their best to work around this, but basically we should find a better approach to reference parameter definitions within Altair.

Thanks for raising!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants