解决matplotlib/IPython Notebook中生成空PNG或PDF图像的问题

142 阅读2分钟

有人在使用matplotlib和IPython Notebook进行数据可视化时遇到了一个问题:生成的PNG或PDF图像为空白,而绘图在IPython Notebook中显示正确。导致该问题的代码示例如下:

import matplotlib.pyplot as plt
import numpy as np

fig = matplotlib.pyplot.gcf()

GCEMA = (0.26, 0.26, 0.30, 0.51, 0.55, 0.34)
CEM = (0.26, 0.23, 0.30, 0.49, 0.35, 0.24)
selSCAN = (0.19, 0.35, 0.28, 0.45, 0.41, 0.52)
selSCANAD = (0.26, 0.52, 0.37, 0.46, 0.46, 0.47)
N = 6
pos = np.arange(N)
ax = plt.axes()

ax.bar(0.6 * pos, GCEMA, width=0.10, color='green', label='GCE-MA')
ax.bar(0.6 * pos + 0.1, CEM, 0.10, color='blue', label='CE-M')
ax.bar(0.6 * pos + 0.2, selSCAN, 0.10, color='red', label='selSCAN-ND')
ax.bar(0.6 * pos + 0.3, selSCANAD, 0.10, color='yellow', label='selSCAN-AD')
plt.ylabel("quality [$\phi$]", fontsize=14)
fig.set_size_inches(5, 4)
plt.xticks(rotation=15)
plt.xticks([0.2, 0.8, 1.4, 2, 2.6, 3.2],
           ['PGP', 'CAIDA', 'coPapersDBLP', 'soc-LiveJournal', 'uk-2002', 'eu-2005'])
plt.legend(loc=4, fontsize=10)
plt.show()
plt.savefig("cond.png")

2、解决方案

针对上述问题,有以下几种解决方案:

  1. 调整savefig的位置。
    • 将savefig移到show之前。因为如果在show之后调用savefig,则可能导致绘图窗口被关闭,从而无法保存图像。
    • 修改后的代码示例如下:
import matplotlib.pyplot as plt
import numpy as np

fig = matplotlib.pyplot.gcf()

GCEMA = (0.26, 0.26, 0.30, 0.51, 0.55, 0.34)
CEM = (0.26, 0.23, 0.30, 0.49, 0.35, 0.24)
selSCAN = (0.19, 0.35, 0.28, 0.45, 0.41, 0.52)
selSCANAD = (0.26, 0.52, 0.37, 0.46, 0.46, 0.47)
N = 6
pos = np.arange(N)
ax = plt.axes()

ax.bar(0.6 * pos, GCEMA, width=0.10, color='green', label='GCE-MA')
ax.bar(0.6 * pos + 0.1, CEM, 0.10, color='blue', label='CE-M')
ax.bar(0.6 * pos + 0.2, selSCAN, 0.10, color='red', label='selSCAN-ND')
ax.bar(0.6 * pos + 0.3, selSCANAD, 0.10, color='yellow', label='selSCAN-AD')
plt.ylabel("quality [$\phi$]", fontsize=14)
fig.set_size_inches(5, 4)
plt.xticks(rotation=15)
plt.xticks([0.2, 0.8, 1.4, 2, 2.6, 3.2],
           ['PGP', 'CAIDA', 'coPapersDBLP', 'soc-LiveJournal', 'uk-2002', 'eu-2005'])
plt.legend(loc=4, fontsize=10)
plt.savefig("cond.png")
plt.show()
  1. 指定bbox_inches参数。
    • 在调用savefig时,指定bbox_inches参数以限制要保存的绘图区域。
    • 修改后的代码示例如下:
import matplotlib.pyplot as plt
import numpy as np

fig = matplotlib.pyplot.gcf()

GCEMA = (0.26, 0.26, 0.30, 0.51, 0.55, 0.34)
CEM = (0.26, 0.23, 0.30, 0.49, 0.35, 0.24)
selSCAN = (0.19, 0.35, 0.28, 0.45, 0.41, 0.52)
selSCANAD = (0.26, 0.52, 0.37, 0.46, 0.46, 0.47)
N = 6
pos = np.arange(N)
ax = plt.axes()

ax.bar(0.6 * pos, GCEMA, width=0.10, color='green', label='GCE-MA')
ax.bar(0.6 * pos + 0.1, CEM, 0.10, color='blue', label='CE-M')
ax.bar(0.6 * pos + 0.2, selSCAN, 0.10, color='red', label='selSCAN-ND')
ax.bar(0.6 * pos + 0.3, selSCANAD, 0.10, color='yellow', label='selSCAN-AD')
plt.ylabel("quality [$\phi$]", fontsize=14)
fig.set_size_inches(5, 4)
plt.xticks(rotation=15)
plt.xticks([0.2, 0.8, 1.4, 2, 2.6, 3.2],
           ['PGP', 'CAIDA', 'coPapersDBLP', 'soc-LiveJournal', 'uk-2002', 'eu-2005'])
plt.legend(loc=4, fontsize=10)
plt.savefig("cond.png", bbox_inches='tight')
plt.show()
  1. 使用backend参数。
    • 在调用savefig时,指定backend参数以指定用于绘图的图形后端。
    • 修改后的代码示例如下:
import matplotlib.pyplot as plt
import numpy as np

fig = matplotlib.pyplot.gcf()

GCEMA = (0.26, 0.26, 0.30, 0.51, 0.55, 0.34)
CEM = (0.26, 0.23, 0.30, 0.49, 0.35, 0.24)
selSCAN = (0.19, 0.35, 0.28, 0.45, 0.41, 0.52)
selSCANAD = (0.26, 0.52, 0.37, 0.46, 0.46, 0.47)
N = 6
pos = np.arange(N)
ax = plt.axes()

ax.bar(0.6 * pos, GCEMA, width=0.10, color='green', label='GCE-MA')
ax.bar(0.6 * pos + 0.1, CEM, 0.10, color='blue', label='CE-M')
ax.bar(0.6 * pos + 0.2, selSCAN, 0.10, color='red', label='selSCAN-ND')
ax.bar(0.6 * pos + 0.3, selSCANAD, 0.10, color='yellow', label='selSCAN-AD')
plt.ylabel("quality [$\phi$]", fontsize=14)
fig.set_size_