简体   繁体   English

如何在 Altair 的标准化条形图中放置分数标签?

[英]How to put fraction labels in normalized bar chart in Altair?

import altair as alt
from vega_datasets import data

# get iris dataset and take 120 observations from it
source = data.iris()[10:130]
# add one more feature to dataset
colors = ['red', 'orange', 'blue', 'red'] * 30
source['colors'] = colors

chart = alt.Chart(source).mark_bar().encode(
    alt.Y('species:N', sort='x'),
    alt.X('count():Q', stack='zero'),
    color=alt.Color('colors', sort=colors), 
    order="colors",
    
)

text = alt.Chart(source).mark_text(dx=-7, dy=3, color='white')\
    .encode(
    alt.Y("species:N", sort='x'),
    alt.X('count():Q', stack="zero"),
    order="colors",
    text=alt.Text('count():Q')
    )

chart + text

结果是带有标签的条形图,显示每个“颜色”特征的计数

Now I want to normalize this chart and labels should represent fraction of a whole.现在我想标准化这个图表,标签应该代表整体的一小部分。

import altair as alt
from vega_datasets import data

source = data.iris()[10:130]
colors = ['red', 'orange', 'blue', 'red'] * 30
source['colors'] = colors


chart = alt.Chart(source).mark_bar().encode(
    alt.Y('species:N', sort='x'),
    alt.X('count():Q', stack='normalize'),
    color=alt.Color('colors', sort=colors), 
    order="colors",
    
)

text = alt.Chart(source).mark_text(dx=-7, dy=3, color='white')\
    .encode(
    alt.Y("species:N", sort='x'),
    alt.X('count():Q', stack="normalize"),
    order="colors",
    text=alt.Text('count():Q')
    )

chart + text

标准化条形图

So in this example instead of 8, 7, 15 for 1st bar I want to see 0.27, 0.23, 0.5 (rounded to 2 digits after comma).所以在这个例子中,第一个小节不是 8、7、15,我想看到 0.27、0.23、0.5(在逗号后四舍五入到 2 位)。 How can I achieve this?我怎样才能做到这一点?

update This is how I managed to progress:更新这就是我设法取得进展的方式:

import altair as alt
from vega_datasets import data

source = data.iris()[10:130]
colors = ['red', 'orange', 'blue', 'red'] * 30
sort_order=['blue', 'orange', 'red']
source['colors'] = colors

chart = alt.Chart(source).mark_bar().encode(
    alt.Y('species:N', sort='x'),
    alt.X('count():Q', stack='normalize'),
    color=alt.Color('colors', sort=sort_order), 
    order = 'colors'
)

text = alt.Chart(source).transform_aggregate(count='count()', groupby=['species', 'colors'])\
    .transform_joinaggregate(total='sum(count)', groupby=["species"])\
    .transform_calculate(frac=alt.datum.count / alt.datum.total)\
    .mark_text(align='right', dx=-7, dy=3, color='white')\
    .encode(
    alt.Y("species:N", sort='x'),
    alt.X('count():Q', stack="normalize"),
    text=alt.Text('frac:Q', format='.0%'),
    order = 'colors'
    )

chart + text

在此处输入图片说明

But labels are not aligned correctly (I need them to be just at the end of each color, just how in first two pictures).但是标签没有正确对齐(我需要它们就在每种颜色的末尾,就在前两张图片中)。 Any ideas how to fix it?任何想法如何解决它?

You can use a series of joinaggregate and calculate transforms to compute the values you wish to display.您可以使用一系列joinaggregate计算转换来计算您希望显示的值。 You can use the format text property to adjust the format using a d3-format string, and the align mark property to adjust the alignment.您可以使用format text 属性使用d3 格式字符串调整格式,并使用align mark 属性调整对齐方式。 For example:例如:

import altair as alt
from vega_datasets import data

source = data.iris()[10:130]
colors = ['red', 'orange', 'blue', 'red'] * 30
source['colors'] = colors
sort_order=['blue', 'orange', 'red']


chart = alt.Chart(source).mark_bar().encode(
    alt.Y('species:N', sort='x'),
    alt.X('count():Q', stack='normalize'),
    color=alt.Color('colors', sort=sort_order), 
    order="colors",
    
)

text = chart.transform_joinaggregate(
    count='count()',
    groupby=['species', 'colors']
).transform_joinaggregate(
    total='count()',
    groupby=['species']
).transform_calculate(
    fraction='datum.count / datum.total'   
).mark_text(
    dx=-7, dy=3, align='right'
).encode(
    color=alt.ColorValue('white'),
    text=alt.Text('fraction:Q', format='.2')
)

chart + text

在此处输入图片说明

(Note: I also made the script a bit more concise by sharing the data and encodings between the two charts) (注意:我还通过在两个图表之间共享数据和编码使脚本更加简洁)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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