Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I keep area coloring consistent in Altair facet charts?

Tags:

python

altair

I want to keep my shaded areas transparent enough to see the grid underneath. All three of the facets end up different shades of gray. I want them to all look like the first one. Sample:

import altair as alt
from vega_datasets import data

source = data.cars()
source['Start'] = 100
source['Middle'] = 175
source['End'] = 250

cars = alt.Chart(source).mark_circle(size=100).encode(
    x=alt.X("Horsepower:Q"),
    y=alt.Y("Miles_per_Gallon:Q"),
    color=alt.Color('Weight_in_lbs:Q'))

area1 = alt.Chart(source).mark_rect(color='#696969',opacity=0.005).encode(
    x=alt.X('Start'), 
    x2='Middle', 
    y=alt.value(0), 
    y2=alt.value(300))

area2 = alt.Chart(source).mark_rect(color='#696969',opacity=0.01).encode(
    x=alt.X('Middle'),
    x2='End',
    y=alt.value(0), 
    y2=alt.value(300))
  
(area1+area2+cars).properties(height=300, width=300
).facet(alt.Column('Origin:N'))

Output: enter image description here

like image 772
pray4shell Avatar asked Oct 27 '25 14:10

pray4shell


1 Answers

The issue is that each row has a start/middle/end value, and so you are stacking one semi-transparent rectangle per point in each facet. Since the facets have different numbers of points, there are different numbers of rectangles, and the resulting shading appears darker or lighter.

The easiest way to fix this would be to use an aggregate in order to draw only a single rectangle per panel:

import altair as alt
from vega_datasets import data

source = data.cars()
source['Start'] = 100
source['Middle'] = 175
source['End'] = 250

cars = alt.Chart(source).mark_circle(size=100).encode(
    x=alt.X("Horsepower:Q"),
    y=alt.Y("Miles_per_Gallon:Q"),
    color=alt.Color('Weight_in_lbs:Q'))

area1 = alt.Chart(source).mark_rect(color='#696969',opacity=0.1).encode(
    x='min(Start)', 
    x2='min(Middle)', 
    y=alt.value(0), 
    y2=alt.value(300))

area2 = alt.Chart(source).mark_rect(color='#696969',opacity=0.2).encode(
    x='min(Middle)',
    x2='min(End)',
    y=alt.value(0), 
    y2=alt.value(300))
  
(area1+area2+cars).properties(height=300, width=300
).facet(alt.Column('Origin:N'))

enter image description here

like image 191
jakevdp Avatar answered Oct 30 '25 15:10

jakevdp