Search code examples
python-3.xdata-visualizationjupyter-labaltair

Altair chart not displaying when evaluated within a function


The following code, taken from the Altair docs, correctly displays in my Jupyter Lab notebook.

import altair as alt
from vega_datasets import data

source = data.seattle_temps.url

alt.Chart(
    source,
    title="2010 Daily High Temperature (F) in Seattle, WA"
).mark_rect().encode(
    x='date(date):O',
    y='month(date):O',
    color=alt.Color('max(temp):Q', scale=alt.Scale(scheme="inferno")),
    tooltip=[
        alt.Tooltip('monthdate(date):T', title='Date'),
        alt.Tooltip('max(temp):Q', title='Max Temp')
    ]
).properties(width=550)

enter image description here

However, if I cut and paste that exact code in a function, and then call the function, the chart no longer displays.

import altair as alt
from vega_datasets import data

def visualize():
    source = data.seattle_temps.url
    alt.Chart(
        source,
        title="2010 Daily High Temperature (F) in Seattle, WA"
    ).mark_rect().encode(
        x='date(date):O',
        y='month(date):O',
        color=alt.Color('max(temp):Q', scale=alt.Scale(scheme="inferno")),
        tooltip=[
            alt.Tooltip('monthdate(date):T', title='Date'),
            alt.Tooltip('max(temp):Q', title='Max Temp')
        ]
    ).properties(width=550)
    
visualize()

I read through Altair's display troubleshooting docs, and it seems the most common fix for this specific issue is to ensure that the chart is evaluated, which it is in this case. I'm not writing chart = alt.Chart(...), I'm skipping the assignment and going straight to the evaluation, which is why it worked outside of the function.

Why bother with the function? The reason I want to wrap it in a function is that I have a huge dataset (100 GBs) stored in a database. When I specify a filter to the database, the result is only 600 rows, so very manageable. I want to put this in a Jupyter Lab notebook and make the filter interative for non-technical users, so I created ipython widget for specifying the filter value. When a user specifies a filter in the widget, the widget needs a callback function to trigger the read from the database and produce the visual on the fly.


Solution

  • It is because your function is not returning anything. You are creating the chart, but not returning it so that the Jupyter Notebook can render it. If you write return alt.Chart(... it will work. If you don't want to return anything you can also append .display() to the chart spec inside the function (this also works for displaying charts in loops).