如何让Altair导出JSON时仅保存图表用到的DataFrame列?
让Altair导出JSON时仅保留图表用到的列
默认情况下,Altair导出JSON会包含原始DataFrame的所有列,手动提前子集化数据过于繁琐。以下是规范的自动处理方法:
1. 提取图表用到的所有字段
先写一个辅助函数,遍历图表的编码配置,收集所有实际用到的字段名:
import altair as alt from vega_datasets import data def get_used_fields(chart): used_fields = set() chart_dict = chart.to_dict() # 处理encoding中的各个属性 if "encoding" in chart_dict: for enc in chart_dict["encoding"].values(): # 处理单个字段的情况(如x、y、color) if isinstance(enc, dict) and "field" in enc: used_fields.add(enc["field"]) # 处理tooltip这类数组格式的字段集合 elif isinstance(enc, list): for item in enc: if "field" in item: used_fields.add(item["field"]) return list(used_fields)
2. 筛选数据并导出JSON
提取字段后,对原始DataFrame做子集化,再生成图表保存,或者直接修改图表的字典结构后保存:
方法A:重新生成筛选后的图表
# 原始数据 source = data.cars().loc[:2,:] # 创建原始图表 fg = alt.Chart(source).mark_circle(size=60).encode( x='Horsepower', y='Miles_per_Gallon', color='Origin', tooltip=['Name', 'Horsepower', 'Miles_per_Gallon'] ).interactive() # 获取用到的字段并筛选数据 used_fields = get_used_fields(fg) filtered_source = source[used_fields] # 用筛选后的数据重新创建图表并保存 fg_filtered = alt.Chart(filtered_source).mark_circle(size=60).encode( x='Horsepower', y='Miles_per_Gallon', color='Origin', tooltip=['Name', 'Horsepower', 'Miles_per_Gallon'] ).interactive() fg_filtered.save("figure_filtered.json")
方法B:直接修改图表字典(更高效)
不需要重新创建图表,直接修改导出的字典结构替换数据集:
import json # 原始图表 fg = alt.Chart(source).mark_circle(size=60).encode( x='Horsepower', y='Miles_per_Gallon', color='Origin', tooltip=['Name', 'Horsepower', 'Miles_per_Gallon'] ).interactive() # 提取字段并筛选数据 used_fields = get_used_fields(fg) filtered_source = source[used_fields] # 转换图表为字典并替换数据集 chart_dict = fg.to_dict() data_name = chart_dict["data"]["name"] chart_dict["datasets"][data_name] = filtered_source.to_dict("records") # 保存为JSON文件 with open("figure_filtered.json", "w") as f: json.dump(chart_dict, f, indent=2)
效果验证
导出的figure_filtered.json中,数据集仅包含Horsepower、Miles_per_Gallon、Origin、Name这些图表实际用到的列,不会出现Displacement、Cylinders等未使用字段,大幅减小文件体积。
内容的提问来源于stack exchange,提问作者Devil
相关产品推荐
相关产品推荐

