我刚开始使用 Matplotlib,从 Matlab 切换。我在 Windows 7 上通过 python(x,y) 运行 Spyder。
我写了一个小脚本,它的工作是
- 打开几个包含表格数据的 Excel 电子表格
- 对于每张工作表,生成多个饼图 - 每个饼图汇总 Excel 中的一行数据
PdfPages
使用后端在输出文档中的自己的页面上绘制每组饼图。
由于所有饼图共享相同的图例,我想在每张纸上只显示一个“共享”图例。我找到的解决方案如下所示:matplotlib - Legend in separate subplot 将每个饼图放在它自己的subplot
中,然后在另一个窗格中生成一个“虚拟”饼图,生成一个图例,然后使用set_visible(False)
.
第一次循环迭代(即第一个 Excel 电子表格和第一页饼图)很好。然而,随后的循环产生了带有文本标签的图例,但没有彩色框。示例显示在以下 Imgur 链接中(抱歉,由于我是 Stackoverflow 的新手,所以我还不能发布图像)。http://i.imgur.com/0ssak1O.png
该问题似乎影响了PdfPages
后端生成的输出,但不影响默认的图形后端(TkAgg
?不确定 Spyder 默认使用哪一个)。PDFfile.savefig()
您可以通过注释掉和取消注释在下面的精简脚本中看到这一点plt.show()
。
因此,总而言之,这个问题似乎源于.set_visible()
跨循环“记住”的方法......但它影响PdfPages
后端,而不是图形后端。我完全困惑,但希望这篇文章对其他人有意义。任何帮助表示赞赏:-)
import xlrd, numpy as np, matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
PDFfile = PdfPages('output.pdf')
for i in range(4):
pieData = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 0, 1, 2]]
pieSliceLabels = ['A', 'B', 'C', 'D']
pieLabels = ['1', '2', '3']
# now, generate some pie plots
plt.figure(0, figsize=(6,2))
numPies = len(pieLabels)
for thisPie in range(numPies):
ax = plt.subplot(1,4,1+thisPie)
plt.title(pieLabels[thisPie])
fracs = pieData[thisPie]
plt.pie(fracs)
# Since all three pie plots share the same data labels, I'd rather just
# generate a single legend that they all share.
# The method I used comes from here:
# https://stackoverflow.com/questions/11140311/matplotlib-legend-in-separate-subplot
# First, generate a "dummy pie" containing same data as last pie.
plt.subplot(1,4,4)
DummyPie = plt.pie(fracs)
# next, generate a big ol' legend
plt.legend(pieSliceLabels, loc='center',prop={'size':'small'})
# finally, hide the pie.
for Pieces in DummyPie:
for LittlePiece in Pieces:
LittlePiece.set_visible(False)
# NOW, HERE'S WHERE IT GETS WEIRD...
# Leave the following line uncommented:
PDFfile.savefig()
# ... and a PDF is generated where the legend colors are shown
# properly on the first page, but not thereafter!
# On the other hand.... comment out "PDF.savefig()" above, and
# uncomment the following line:
# plt.show()
# ...and the figures will be generated onscreen, WITHOUT the legend
# problem!!
PDFfile.close()