1

基于这篇文章,我能够构建一个标准化的分层直方图。但是,似乎标准化是针对样本总数而不是每个类别的样本总数进行的。我想知道如何使用 altair 对每个类别进行标准化?

例子:

import pandas as pd
import altair as alt

source = pd.DataFrame({'age': ['12', '32', '43', '54', '32', '32', '12','20','44','24'],'gender': ['m','m','f','f','f','m','f','m','f','m']})

alt.Chart(source).transform_joinaggregate(
    total='count(*)'
).transform_calculate(
    pct='1 / datum.total'
).mark_bar().encode(
    alt.X('age:Q', bin=True),
    alt.Y('sum(pct):Q', axis=alt.Axis(format='%')),
    color='gender'
)

在此处输入图像描述

4

3 回答 3

3

如果要在特定类别中进行标准化,可以通过将 a 添加groupby到聚合转换来计算该类别中的总数:

import pandas as pd
import altair as alt

source = pd.DataFrame({
    'age': ['12', '32', '43', '54', '32', '32', '12','20','44','24'],
    'gender': ['m','m','f','f','f','m','f','m','f','m']
})

alt.Chart(source).transform_joinaggregate(
    total='count(*)',
    groupby=['gender']
).transform_calculate(
    pct='1 / datum.total'
).mark_bar().encode(
    alt.X('age:Q', bin=True),
    alt.Y('sum(pct):Q', axis=alt.Axis(format='%')),
    color='gender'
)

在此处输入图像描述

于 2020-06-16T14:16:33.893 回答
2

如果我理解正确,我认为传递stack='normalize'给 y 编码应该可以。

import pandas as pd
import altair as alt

source = pd.DataFrame({
    'age': ['12', '32', '43', '54', '32', '32', '12','20','44','24'],
    'gender': ['m','m','f','f','f','m','f','m','f','m']
    })

alt.Chart(source).mark_bar().encode(
    alt.X('age:O', bin=True),
    alt.Y('count()',
          stack='normalize', 
          axis=alt.Axis(title='Group Percentage', format='%'), 
          ),
    color='gender'
)

在此处输入图像描述

于 2020-06-15T15:13:34.223 回答
1
bins = [10+5*i for i in range(10)]
df_plot = pd.crosstab(source.gender, pd.cut(source.age, bins=bins)).apply(lambda r: r/r.sum(), axis=0).stack().reset_index().rename(columns={0:'perc'})

df_plot['age'] = df_plot['age'].astype(str)

alt.Chart(df_plot).mark_bar().encode(
  x='age:N',
  y=alt.Y('perc:Q', axis=alt.Axis(format='%'), stack=False),
  color='gender:N',
  opacity=alt.value(0.6)
)

Altair 图,每组和每箱的百分比

但也许问题是如何让两组的百分比彼此相邻?

于 2020-06-15T15:32:59.080 回答