python-3.xdataframestreamlitaltair

Undefined colors in Altair plot


I have been making a program in Python with the help of the libraries Altair and Streamlit in order to visualize data on a real time updating dashboard locally. I'll be the first to admit that these are uncharted territories for me as I've only had experiences with C before and I'm learning with every step of the way. Currently I'm pulling the values through the OpenF1 API and converting them to RGBA by adding a '#' in front of the string. I then sort them by driver, add them to a pandas dataframe (which also includes all other values relevant to the violin plot) and pass the structure to the alt.Chart() function. Unfortunately Altair seems to not recognise these values and assignes a blue color to the whole chart.

    lapViolin = alt.Chart(data2, width=100).transform_density(
        'Laptime',
        as_=['Laptime','density'],
        groupby=['Driver']
    ).mark_area(orient='horizontal').encode(
        x=alt.X('density:Q')
            .stack('center')
            .title(None)
            .impute(None)
            .axis(labels=False, values=[0], grid=False, ticks=True),
        y=alt.Y('Laptime:Q'),
        color=alt.Color('Team'),
        column=alt.Column('Driver:N')
            .spacing(0)
            .header(titleOrient='bottom', labelOrient='bottom', labelPadding=0)
    ).configure_view(
        stroke=None
    )
    st.altair_chart(lapViolin)

Violin plot

I have tried making another graph I needed for the project, which is a scatter plot using both color='Team' and the alt.Column() function but it outputs predetermined colors only this time the points of the scatter plot are at least grouped correctly. Scatter plot


Solution

  • The customization section in the docs includes an example of how to use raw color values by setting .scale(None):

    import pandas as pd
    import altair as alt
    
    data = pd.DataFrame({
        'x': range(6),
        'color': ['red', 'steelblue', 'chartreuse', '#F4D03F', '#D35400', '#7D3C98']
    })
    
    alt.Chart(data).mark_point(
        filled=True,
        size=100
    ).encode(
        x='x',
        color=alt.Color('color').scale(None)
    )