使用hist2d不等分bins时调用savefig出现报错求助
解决Matplotlib hist2d不等分bins时savefig报错的问题
我碰到过类似的问题,这其实是Matplotlib旧版本的一个已知bug——当你使用不等宽的自定义bins绘制hist2d时,生成的QuadMesh对象的_extent属性没有被正确初始化,导致调用savefig(尤其是带bbox_inches='tight'参数时)触发了TypeError。
问题根源
你用的Matplotlib版本(从报错路径看是基于Python3.5的Anaconda包,对应Matplotlib应该是2.x系列)在处理不等宽bins的hist2d时,没有正确计算并设置网格的范围属性,当savefig尝试获取元素的窗口范围时,_extent是None,就抛出了迭代空对象的错误。
解决方法
方法1:手动设置QuadMesh的_extent属性
在调用savefig之前,手动给生成的QuadMesh对象指定_extent值,这个值就是你的x和y bins的最小、最大值:
import matplotlib.pyplot as plt import numpy as np fig1, ax1 = plt.subplots(figsize=(8,5)) x = np.random.randn(100000) y = np.random.randn(100000)+5 # 定义不等分bins x_bins = [0,1,2,3] y_bins = [2,3,5,6] h = ax1.hist2d(x, y, bins=(x_bins, y_bins)) # 获取QuadMesh对象 mesh = h[3] # 手动设置_extent:[xmin, xmax, ymin, ymax] mesh._extent = [x_bins[0], x_bins[-1], y_bins[0], y_bins[-1]] fig1.savefig('test2.pdf', bbox_inches='tight') plt.close()
方法2:升级Matplotlib到最新稳定版
这个bug在Matplotlib 3.0及以后的版本中已经被修复了。如果你能升级你的Matplotlib环境,直接执行:
pip install --upgrade matplotlib
升级后再运行你的原代码就不会报错了。
方法3:用pcolormesh替代hist2d绘制二维直方图
如果暂时无法升级版本,也可以用numpy.histogram2d先计算直方图数据,再用pcolormesh绘制,这样可以避开这个bug:
import matplotlib.pyplot as plt import numpy as np fig1, ax1 = plt.subplots(figsize=(8,5)) x = np.random.randn(100000) y = np.random.randn(100000)+5 x_bins = [0,1,2,3] y_bins = [2,3,5,6] # 先计算直方图数据 counts, x_edges, y_edges = np.histogram2d(x, y, bins=(x_bins, y_bins)) # 用pcolormesh绘制 mesh = ax1.pcolormesh(x_edges, y_edges, counts.T) # 添加颜色条 fig1.colorbar(mesh) fig1.savefig('test2.pdf', bbox_inches='tight') plt.close()
注意这里counts需要转置(.T),因为pcolormesh的维度顺序和histogram2d输出的一致。
内容的提问来源于stack exchange,提问作者Phil
相关产品推荐
相关产品推荐

