How to make Altair display NaN points with a quantitative color scale?

Viewed 53

In Altair, is there a way to plot NaN/None colors in quantitative encodings? Possibly even assigning a specific color such as in Matplotlib's set_bad?

For example, the third data point is missing using quantitative encoding for color 'c:Q'

df = pd.DataFrame(dict(x=[0, 1, 2, 3], c=[0, 1, None, 3]))
alt.Chart(df).mark_circle().encode(x='x:Q', y='x:Q', color='c:Q')

enter image description here

but it shows up (as null) when using ordinal encoding 'c:O':

df = pd.DataFrame(dict(x=[0, 1, 2, 3], c=[0, 1, None, 3]))
alt.Chart(df).mark_circle().encode(x='x:Q', y='x:Q', color='c:O')

enter image description here

1 Answers

Null data is filtered by default for some chart types and scales, but we can include them with invalid=None (the "invalid" param for marks in the docs). Then we can use a condition that assigns points the color grey if they are not valid numerical data:

import pandas as pd
import altair as alt


df = pd.DataFrame(dict(x=[0, 1, 2, 3], c=[0, 1, None, 3]))

alt.Chart(df).mark_circle(size=200, invalid=None).encode(
    x='x:Q',
    y='x:Q',
    color=alt.condition('isValid(datum.c)', 'c:Q', alt.value('gray'))
)

enter image description here

If you want the legend to include the NaN, I think you need a layered chart:

points = alt.Chart(df).mark_circle(size=200).encode(
    x='x:Q',
    y='x:Q',
    color='c:Q'
)

points + points.encode(
    color=alt.Color('c:O', scale=alt.Scale(range=['grey']), title=None)
).transform_filter(
    '!isValid(datum.c)'
)

enter image description here

It would be convenient if you could avoid layering and simply type out something like this instead, but that is not allowed currently:

    alt.condition(
        'isValid(datum.c)',
        'c:Q',
        alt.Color('c:O', scale=alt.Scale(range=['grey']), title=None)
    )

Ref Dealing with missing values / nulls in Altair choropleth map

Related