如何将matplotlib绘制的统计图表数据存入JSON对象
实现方法
JSON本身仅支持字符串、数值、数组、布尔值、普通对象这类可序列化结构,无法直接存储matplotlib的绘图对象,你可以根据需求选择以下两种方案:
方案1:存储图表原始计算数据
该方案占用空间小,后续可基于数据重新渲染、调整图表样式,适合需要二次编辑图表的场景。
你需要修改函数,在绘图的同时收集各类图表的计算结果,最后汇总到JSON中:
import json import numpy as np import matplotlib.pyplot as plt from scipy import stats # 先初始化空JSON对象 plots_json = {} def statistical_plots(desired_column): values = given_df.loc[:, desired_column].values fig, axes = plt.subplots(nrows=2, ncols=2, figsize=[8, 8]) plot_data = {} # 直方图数据收集+绘制 hist_counts, hist_bins = np.histogram(values, bins='auto') plot_data['histogram'] = { 'counts': hist_counts.tolist(), 'bins': hist_bins.tolist() } axes[0,0].hist(values, bins='auto') axes[0,0].set_title('Histogram') # 箱线图数据收集+绘制 q1 = np.percentile(values,25) q3 = np.percentile(values,75) iqr = q3 - q1 plot_data['boxplot'] = { 'min': float(values.min()), 'q1': float(q1), 'median': float(np.median(values)), 'q3': float(q3), 'max': float(values.max()), 'outliers': [float(v) for v in values if v < q1 - 1.5*iqr or v > q3 + 1.5*iqr] } axes[0,1].boxplot(values) axes[0,1].set_title('Boxplot') # Q-Q图数据收集+绘制 qq_theoretical, qq_sample = stats.probplot(values, fit=False) plot_data['qq_plot'] = { 'theoretical_quantiles': qq_theoretical.tolist(), 'sample_quantiles': qq_sample.tolist() } stats.probplot(values, plot=axes[1,0]) axes[1,0].set_title('Q-Q Plot') # P-P图数据收集+绘制 sorted_vals = np.sort(values) mean_val = np.mean(values) std_val = np.std(values) cdf_vals = stats.norm.cdf(sorted_vals, loc=mean_val, scale=std_val) pp_percentiles = np.arange(1, len(values)+1) / len(values) plot_data['pp_plot'] = { 'theoretical_cdf': cdf_vals.tolist(), 'sample_percentiles': pp_percentiles.tolist() } axes[1,1].plot(pp_percentiles, cdf_vals, 'o') axes[1,1].plot([0,1],[0,1], 'r--') axes[1,1].set_title('P-P Plot') plt.suptitle(f'Basic Statistical Plots of {desired_column}') fig.tight_layout() plt.close(fig) # 避免多余内存占用 # 把当前列的图表数据加入JSON对象 plots_json[f'Basic Statistical Plots of {desired_column}'] = plot_data # 遍历所有列生成数据 for col in given_df.columns: statistical_plots(col) # 最后可导出为JSON文件 with open('plots_data.json', 'w', encoding='utf-8') as f: json.dump(plots_json, f, ensure_ascii=False, indent=2)
方案2:存储渲染后的图表Base64字符串
如果需要保存完整的已渲染图表样式,不需要后续调整,可直接将图表转为Base64编码的图片字符串存入JSON:
import json import base64 from io import BytesIO import matplotlib.pyplot as plt plots_json = {} def statistical_plots(desired_column): values = given_df.loc[:, desired_column].values fig, axes = plt.subplots(nrows=2, ncols=2, figsize=[8, 8]) # 此处保留你原有4张图的绘制逻辑不变 # ... plt.suptitle(f'Basic Statistical Plots of {desired_column}') fig.tight_layout() # 把图表转为Base64字符串 buffer = BytesIO() plt.savefig(buffer, format='png', dpi=75, bbox_inches='tight') buffer.seek(0) img_base64 = base64.b64encode(buffer.read()).decode('utf-8') plt.close(fig) plots_json[f'Basic Statistical Plots of {desired_column}'] = { 'image_base64': img_base64, 'image_format': 'png' } # 遍历所有列生成数据 for col in given_df.columns: statistical_plots(col) # 导出JSON文件 with open('plots_images.json', 'w', encoding='utf-8') as f: json.dump(plots_json, f, ensure_ascii=False, indent=2)
后续需要使用图片时,直接将image_base64字段的内容加前缀data:image/png;base64,即可在前端页面展示、或解码写入本地生成PNG文件。
内容的提问来源于stack exchange,提问作者SupernovifieD
相关产品推荐
相关产品推荐

