ViniciusAxe
ViniciusAxe

Reputation: 33

How to configure bars in a altair.layered plot?

While using streamlit I started to use altair to plot data. While using it I stumbled across following problem:

I want to plot a DataFrame that has the following structure:

workload_df = pd.DataFrame({
    'index': pd.to_datetime(['01.02.2010', '01.03.2010', '01.04.2010']),
    'measure': [100, 90, 120],
    'measure_max': [80, 100, 150],
})

Now I want to compare the measure with the max_measure in a bar plot:

measure_max_plot = alt.Chart(workload_df).mark_bar(color = 'lightgreen', text = 'measure_max').encode(
        alt.X('index', title = '', axis = alt.Axis(labelAngle = -45, labelOverlap = False)),
        alt.Y('measure_max', title = '')
)

measure_plot = alt.Chart(workload_df).mark_bar(text = 'measure').encode(
   x = alt.X('index', title = 'X', axis = alt.Axis(labelAngle = -45, labelOverlap = False)), 
   y = alt.Y('measure', title = 'Y'),

   color=alt.condition(
       alt.datum.measure > alt.datum.measure_max,  
       alt.value('red'),     
       alt.value('steelblue')   
   )
)
altair_plot = alt.layer(measure_max_plot, measure_plot)
st.altair_chart(altair_plot, use_container_width=True)

I get something like this:

Data_Plot 1

or something like that:

Data_Plot 2

But I want that the highest bar will always be in the background, so something like this:

Final Solution

Could anyone help me with this problem ?

Upvotes: 1

Views: 283

Answers (1)

jakevdp
jakevdp

Reputation: 86310

Layers are always shown in the order they are specified in the layer chart. In your case, you want part of the measure_plot shown below measure_max_plot, and part shown above. You can do that by filtering and adding another layer:

altair_plot = alt.layer(
    measure_plot.transform_filter(alt.datum.measure > alt.datum.measure_max),
    measure_max_plot,
    measure_plot.transform_filter(alt.datum.measure < alt.datum.measure_max)
)

enter image description here

Upvotes: 1

Related Questions