在Jupyter Notebook中保存Pandas绘图出现空白图的问题求助
解决Jupyter中Pandas绘图保存为空白图片的问题
我之前在Jupyter Notebook里处理Spark转Pandas绘图保存时,也碰到过一模一样的问题——保存出来的图片只有几十字节,完全空白。大概率是Matplotlib的后端设置或者绘图保存的顺序出了问题,咱们来一步步修复:
先梳理你的代码(格式化后)
# 从Spark SQL获取数据 EperDtDF = spark.sql("SELECT timestamp, data.ldr from deviceData where timestamp >= '2018-05-01T00:00:00+02:00' and timestamp < '2018-05-07T23:59:59+02:00'") EperDtDF.cache() # 转换为Pandas DataFrame并设置索引 EperDtPanda = EperDtDF.toPandas().set_index('timestamp') # 绘制切片数据的图表 slice_plot = EperDtPanda[0:4321].plot() # 取前6小时的数据 fig = slice_plot.get_figure() # 推测你这里应该有保存代码,比如 fig.savefig('your_plot.png')
核心问题与修复方案
1. 先在Jupyter中初始化Matplotlib后端
Jupyter的Matplotlib默认后端可能不会自动渲染图像到可保存的对象里,先运行这行魔法命令:
%matplotlib inline
这会让图像直接嵌入Notebook,同时确保绘图对象能被正确写入文件。如果用的是新版Jupyter Lab,也可以试试%matplotlib widget,交互性更强,同样能解决保存问题。
2. 调整保存顺序,确保绘图完成后再执行保存
有时候如果保存操作过早,图像还没完成渲染就被写入文件了。可以显式触发渲染后再保存:
import matplotlib.pyplot as plt # 绘制图表 slice_plot = EperDtPanda[0:4321].plot() # 显式渲染图像(确保绘图完成) plt.draw() # 获取图对象并保存 fig = slice_plot.get_figure() # 加上bbox_inches='tight'防止边缘裁剪,dpi控制清晰度 fig.savefig('ldr_timeseries.png', dpi=120, bbox_inches='tight') # 可选:关闭图对象释放内存 plt.close(fig)
3. 先确认你的数据是否有效
空白图也可能是因为切片后的DataFrame没有数据!先检查一下:
print("切片数据行数:", EperDtPanda[0:4321].shape[0]) print("数据预览:") print(EperDtPanda[0:4321].head())
如果输出显示行数为0,那就要回头检查Spark SQL的查询条件是否正确,比如时区、日期格式有没有问题。
4. 改用原生Matplotlib绘图(更可控)
如果Pandas的plot()方法还是有问题,可以直接用Matplotlib的API来绘制,灵活性更高:
import matplotlib.pyplot as plt # 提取要绘制的数据 data_slice = EperDtPanda[0:4321] # 创建画布和轴对象 fig, ax = plt.subplots(figsize=(10, 6)) # 绘制折线图 ax.plot(data_slice.index, data_slice['ldr'], linewidth=0.8) # 设置图表标签和标题 ax.set_xlabel('Timestamp', fontsize=10) ax.set_ylabel('LDR Reading', fontsize=10) ax.set_title('LDR Data - First 6 Hours (May 2018)', fontsize=12) # 旋转x轴标签避免重叠 plt.xticks(rotation=45) # 保存图片 fig.savefig('ldr_plot_matplotlib.png', dpi=120, bbox_inches='tight')
试试上面的方法,应该就能解决空白图片的问题了!
内容的提问来源于stack exchange,提问作者ZelelB




