creating an altair chart based on a dictionary : issue passing pandas dataframe

Viewed 438

I'm trying to generate different altair charts programmatically. I will base those different charts setups on dictionaries with alt.Chart.from_dict().

I've reverse engineered the overall configuration of the charts with an existing chart doing chart.to_dict(), but this method serializes the data into json, whereas my data is hosted in pandas dataframes and I'm struggling to find the right syntax in the dictionary to pass the dataframe.

I've tried a few variations of the below :

d_chart_config = {
    "data": df, #or df.to_dict()
    "config": {
        "view": {"continuousWidth": 400, "continuousHeight": 300},
        "title": {"anchor": "start", "color": "#4b5c65", "fontSize": 20},
    },
    "mark": {"type": "bar", "size": 40},
    ....}

but haven't managed to figure out how or where to insert the dataframe in the dictionary, either as a dataframe directly or as a df.to_dict()

please help if you've managed something similar.

1 Answers

The pure pandas way to generate a Vega-Lite data field is {"values": df.to_dict(orient="records")}, but this has problems in some cases (namely handling of datetimes, categoricals, and non-standard numeric & string types).

Altair has utilities to work around these issues that you can use directly, namely the altair.utils.data.to_values function.

For example:

import pandas as pd
from altair.utils.data import to_values

df = pd.DataFrame({'a': [1, 2, 3], 'b': pd.date_range('2012', freq='Y', periods=3)})

print(to_values(df))
# {'values': [{'a': 1, 'b': '2012-12-31T00:00:00'},
#   {'a': 2, 'b': '2013-12-31T00:00:00'},
#   {'a': 3, 'b': '2014-12-31T00:00:00'}]}

You can use this directly within a dictionary containing a vega-lite specification and generate a valid chart:

alt.Chart.from_dict({
    "data": to_values(df),
    "mark": "bar",
    "encoding": {
        "x": {"field": "a", "type": "quantitative"},
        "y": {"field": "b", "type": "ordinal", "timeUnit": "year"},
    }
})

enter image description here

Related