简体   繁体   中英

How to increase bar spacing in altair

I am trying to create an interactive chart such as when selecting a category, it displays all items in that category, but I haven't found a way to account for the variable height of the lower chart, which depends on the number of items in each category. This is how the chart ideally would show, when selecting category 1:

在此处输入图像描述

And when I select category 2, I would like it to be like this:

在此处输入图像描述

But, if I specify a fixed chart height that accommodates all the items in category 1 with proper spacing, this is what I get when I select category 2:

在此处输入图像描述

If I don't specify a chart height, the bars get too close together and some triangles don't show:

在此处输入图像描述

Here is the code:

df=pd.read_excel('df_test.xlsx')
    
    
domain=[df.Lowest.min(),df.Highest.max()]
    
    
selection=alt.selection_multi(fields=['category'],init=[{"category":"category1"}])
    
   
l=alt.Chart(df,height=80).mark_bar(color='red',size=15).encode(alt.X('min(Lowest)',scale=alt.Scale(domain=domain))
            ,alt.Y('category'),x2='max(middle)')
h=alt.Chart(df).mark_bar(color='green',size=15).encode(alt.X('max(middle)',scale=alt.Scale(domain=domain))
            ,alt.Y('category'),x2='max(Highest)')
avg_triangle=alt.Chart(df).mark_point(size=300,shape='triangle',filled=True,yOffset=-16,angle=180).encode(
    alt.X('mean(Current)',scale=alt.Scale(domain=domain)),alt.Y('category'))

averages=alt.layer(l,h,avg_triangle).add_selection(selection)


low=alt.Chart(df,height=300).mark_bar(color='red',size=15).encode(alt.X('Lowest',scale=alt.Scale(domain=domain))
                ,alt.Y('items'),x2='middle')

high=alt.Chart(df).mark_bar(color='green',size=15).encode(alt.X('middle',scale=alt.Scale(domain=domain))
                ,alt.Y('items'),x2='Highest')

triangle=alt.Chart(df).mark_point(size=300,shape='triangle',filled=True,yOffset=-16,angle=180).encode(
    alt.X('Current',scale=alt.Scale(domain=domain)),alt.Y('items'))
    
items=alt.layer(low,high,triangle).transform_filter(selection)
    

alt.vconcat(averages,items).configure_axis(title=' ')

And this is the dataset:

在此处输入图像描述

And the data for easy grab:

df=pd.DataFrame([{'category': 'category1',
  'items': 'c1-item1',
  'Highest': 77.9674166,
  'Lowest': 64.76344086,
  'middle': 71.36542873,
  'Current': 70.11278195},
 {'category': 'category1',
  'items': 'c1-item2',
  'Highest': 85.71428571,
  'Lowest': 64.38053097,
  'middle': 75.04740834,
  'Current': 84.1},
 {'category': 'category1',
  'items': 'c1-item3',
  'Highest': 82.51879699,
  'Lowest': 62.63736264,
  'middle': 72.578079815,
  'Current': 81.2},
 {'category': 'category1',
  'items': 'c1-item4',
  'Highest': 80.47182176,
  'Lowest': 51.37362637,
  'middle': 65.922724065,
  'Current': 76.69172932},
 {'category': 'category1',
  'items': 'c1-item5',
  'Highest': 85.19003932,
  'Lowest': 55.43010753,
  'middle': 70.310073425,
  'Current': 83.64661654},
 {'category': 'category1',
  'items': 'c1-item6',
  'Highest': 79.45609436,
  'Lowest': 40.56776557,
  'middle': 60.01192996499999,
  'Current': 74.81203008},
 {'category': 'category2',
  'items': 'c2-item1',
  'Highest': 76.14678899,
  'Lowest': 50.0,
  'middle': 63.073394495,
  'Current': 69.17293233},
 {'category': 'category2',
  'items': 'c2-item2',
  'Highest': 81.06159895,
  'Lowest': 58.77956989,
  'middle': 69.92058442,
  'Current': 75.0}])

You can increase the number of pixels used for each nominal step (each bar) by using {"step": <number>} . You can combine this with making bars narrower (ie create more space in between them to accommodate the triangle) using bandPaddingInner :

import altair as alt
import pandas as pd

source = pd.DataFrame({
    'a': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'],
    'b': [28, 55, 43, 91, 81, 53, 19, 87, 52]
})

alt.Chart(source, width=alt.Step(100).mark_bar().encode(
    x='a',
    y='b'
).configure_scale(
    bandPaddingInner=0.5
)

在此处输入图像描述

You will also need to set .configure(autosize=alt.AutoSizeParams(resize=True)) at the end of your concatenated chart in order for the overall chart size (not just the axes) to update on a selection.

In the next version of Altair you will be able to dynamically change the height of a chart using parameters .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM