在Vega-Altair中添加下拉筛选时触发SchemaValidationError求助
问题:Altair柱状图筛选功能触发SchemaValidationError错误
我尝试制作一个带有文本标注的柱状图,通过下拉菜单筛选特定经验级别数据,但运行代码时触发了SchemaValidationError。以下是我的代码及报错信息:
source1_drop = alt.binding_select(options=['EN', 'SE','MI','EX'], name="Experience Level (Source 1)") source1_select = alt.selection_point(fields=['experience_level'], bind=source1_drop) base1 = alt.Chart(data).encode( alt.Y('job_title:N').axis(None) ) bar1 = base1.mark_bar().encode( x='count()' ) text1 = base1.mark_text(align='left', dx=-145).encode( text="job_title:N" ) filter_exp1 = base1.add_params(source1_select).transform_filter(source1_select).properties(title="Exp Level 1")
打印filter_exp1时出现如下错误:
--------------------------------------------------------------------------- SchemaValidationError Traceback (most recent call last) /usr/local/lib/python3.10/dist-packages/altair/vegalite/v5/api.py in to_dict(self, *args, **kwargs) 2511 copy.data = core.InlineData(values=[{}]) 2512 return super(Chart, copy).to_dict(*args, **kwargs) -> 2513 return super().to_dict(*args, **kwargs) 2514 2515 def add_params(self, *params) -> Self: 1 frames /usr/local/lib/python3.10/dist-packages/altair/utils/schemapi.py in to_dict(self, validate, ignore, context) 812 # show the less helpful ValidationError instead of 813 # the more user friendly SchemaValidationError -> 814 raise SchemaValidationError(self, err) from None 815 return result 816 SchemaValidationError: '{'data': {'name': 'data-2abd5e3a76b2610869c698a6f5adde06'}, 'encoding': {'y': {'axis': None, 'field': 'job_title', 'type': 'nominal'}}, 'params': [{'name': 'param_1', 'select': {'type': 'point', 'fields': ['experience_level']}, 'bind': {'input': 'select', 'options': ['EN', 'SE', 'MI', 'EX'], 'name': 'Experience Level (Source 1)'}}], 'title': 'Exp Level 1', 'transform': [{'filter': {'param': 'param_1'}}]}' is an invalid value. 'mark' is a required property alt.Chart(...)
数据样例:包含job_title、experience_level等字段,经验级别取值为EN、SE、MI、EX。
问题原因与解决方案
问题原因
报错提示'mark' is a required property,因为你直接基于base1创建了filter_exp1,但base1只是定义了基础编码,没有指定任何图表标记(mark)类型,而Altair要求所有可渲染的图表必须包含mark属性。
修改后的代码
source1_drop = alt.binding_select(options=['EN', 'SE','MI','EX'], name="Experience Level (Source 1)") source1_select = alt.selection_point(fields=['experience_level'], bind=source1_drop) base1 = alt.Chart(data).encode( alt.Y('job_title:N').axis(None) ) # 给柱状图添加筛选逻辑 bar1 = base1.mark_bar().encode( x='count()' ).add_params(source1_select).transform_filter(source1_select) # 给文本标注添加筛选逻辑 text1 = base1.mark_text(align='left', dx=-145).encode( text="job_title:N" ).add_params(source1_select).transform_filter(source1_select) # 组合柱状图与文本标注,设置标题 filter_exp1 = (bar1 + text1).properties(title="Exp Level 1") # 渲染图表 filter_exp1
修改说明
- 将筛选参数(
add_params)和过滤逻辑(transform_filter)分别应用到已经指定了mark类型的bar1和text1上,确保每个子图表都符合Schema要求。 - 使用
+运算符将柱状图和文本标注组合成一个完整的图表,这样下拉筛选会同时作用于两者。 - 最后给组合后的图表设置标题,完成完整的可渲染图表定义。
内容的提问来源于stack exchange,提问作者jejelim
相关产品推荐
相关产品推荐

