如何在Altair/Streamlit中汇总数据制作分组条形图
实现Python+Altair版按月分组的分组条形图(对应R ggplot2效果)
问题背景
在R中可通过以下代码实现按月分组的分组条形图:
library(tidyverse) library(lubridate) df<-data.frame(mydate=rep(as.Date("2022-01-01")+0:90, each=10), mygroup=sample(c("A", "B", "C"), size=910, replace=T)) df %>% mutate(mymonth=round_date(mydate, "month")) %>% ggplot(aes(x=mymonth, fill=mygroup))+ geom_bar(position = "dodge")
使用Python的Pandas、Altair与Streamlit复刻该图表时,当前代码存在以下问题:
- 生成的是堆叠条形图,而非分组条形图
- 尝试使用
xOffset属性时出现SchemaValidationError错误 - 数据未正确汇总,导致条形出现水平条纹且计数数值错误
当前Python代码:
import streamlit as st #version 1.14.0 import pandas as pd #version 1.5.1 import altair as alt #version 4.2.0 df=pd.DataFrame({'mydate':pd.date_range(start='1/1/2020', end='4/09/2020').repeat(10), 'mygroup':pd.Series(["A", "B", "C"]).sample(n=1000, replace=True)}) c = alt.Chart(df).transform_window( sort=[{'field': 'yearmonth(mydate)'}], cumulative_count='count(*)', # incorrect count ).mark_bar().encode( x='yearmonth(mydate):O', y='cumulative_count:Q', #xOffset='mygroup:N', #error color='mygroup' ) st.altair_chart(c, use_container_width=True)
解决方案
1. 修正数据生成(可选,避免长度不匹配警告)
确保mygroup的长度与mydate完全一致:
date_range = pd.date_range(start='1/1/2020', end='4/09/2020') df = pd.DataFrame({ 'mydate': date_range.repeat(10), 'mygroup': pd.Series(["A", "B", "C"]).sample(n=len(date_range)*10, replace=True) })
2. 正确汇总数据并实现分组条形图
使用transform_aggregate按月份和分组统计数量,再通过mark_bar(position='dodge')实现分组并排效果:
import streamlit as st import pandas as pd import altair as alt # 生成数据 date_range = pd.date_range(start='1/1/2020', end='4/09/2020') df = pd.DataFrame({ 'mydate': date_range.repeat(10), 'mygroup': pd.Series(["A", "B", "C"]).sample(n=len(date_range)*10, replace=True) }) # 创建分组条形图 chart = alt.Chart(df).transform_aggregate( count='count()', groupby=['yearmonth(mydate):O', 'mygroup:N'] ).mark_bar(position='dodge').encode( x=alt.X('yearmonth(mydate):O', title='月份'), y=alt.Y('count:Q', title='数量'), color=alt.Color('mygroup:N', title='分组'), tooltip=['yearmonth(mydate):O', 'mygroup:N', 'count:Q'] ).properties( title='按月分组的数量统计' ) st.altair_chart(chart, use_container_width=True)
关键说明
- 数据汇总:用
transform_aggregate替代transform_window,按月份和分组维度准确统计每组数量,解决计数错误和条纹问题 - 分组条形图实现:通过
mark_bar(position='dodge')让同一月份下的不同分组条形并排显示,无需使用xOffset(该属性并非此场景的标准用法,且存在版本兼容性问题) - 优化细节:添加标题、坐标轴标签和tooltip,提升图表可读性
内容的提问来源于stack exchange,提问作者M.Viking
相关产品推荐
相关产品推荐

