I'm just starting out with Matplotlib, switching from Matlab. I run Spyder through python(x,y) on Windows 7.
I wrote a little script whose job is to
- Open several Excel spreadsheets containing tabular data
- For each sheet, generate several pie plots - each summarizing one row of data from Excel
- Plot each group of pie plots on its own page in an output document, using the
PdfPages
backend.
Since all pie plots share the same legend, I wanted to show just one "shared" legend on each sheet. The solution I found is shown here: matplotlib - Legend in separate subplot Place each pie plot in its own subplot
, then generate a "dummy" pie in another pane, generate a legend, then hide all the pie's pieces using set_visible(False)
.
The first loop iteration (i.e., first Excel spreadsheet and first page of pie plots) was fine. However, subsequent loops yielded legends with text labels, but without colored boxes. Example is shown at the following Imgur link (sorry, I can't post images yet since I'm new to Stackoverflow). https://i.stack.imgur.com/O0ufi.png
The problem seems to affect the output generated by the PdfPages
backend, but not the default graphical backend (TkAgg
? not sure which one Spyder uses by default). You can see this in my stripped-down script below by commenting out PDFfile.savefig()
and uncommenting plt.show()
.
So, in summary, this problem seems to stem from the .set_visible()
methods being "remembered" across loops... but it affects the PdfPages
backend, not the graphical one. I'm utterly confused, but hoping this post makes sense to others. Any help appreciated :-)
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()