سؤال

I'm trying to put a matplotlib graph onto a reportlab canvas. I can do a simple graph with the code from this question: How to drawImage a matplotlib figure in a reportlab canvas? But when I try to use subplots or use multiple plots it will not work properly. Doing it this way causes the same image to be plotted twice even when I added things like imgdata.close() or deleting the figure:

    from matplotlib.figure import Figure
    import cStringIO
    from reportlab.pdfgen import canvas
    from reportlab.lib.utils import ImageReader       

    can = canvas.Canvas()
    self.f = Figure()
    plot(x,y)
    xlabel(xlbl)
    ylabel(ylbl)

    imgdata=cStringIO.StringIO()
    savefig(imgdata,format='png')
    imgdata.seek(0)
    Image = ImageReader(imgdata)
    can.drawImage(Image,100,250, width=400,height=350)

    self.g = Figure()
    plot(x,y)
    xlabel(xlbl)
    ylabel(ylbl)

    secondimgdata = cStringIO.StringIO()
    savefig(secondimgdata,format='png')
    secondimgdata.seek(0)

    Image2 = ImageReader(secondimgdata)
    can.drawImage(Image2,100,150, width=400,height=350)

When trying with subplots it simply produces a blank graph and I did not know where to go with it:

    self.f = Figure()
    self.a = self.f.add_subplot(111)
    self.a.plot(x,y)
    self.a2 =self.a.twinx()
    self.a2.plot(x,y2,'r')
    self.a2.set_ylabel(ylbl2)
    self.a.set_xlabel(xlbl)
    self.a.set_ylabel(ylbl)

Any solution or advice to this problem would be very much appreciated.

هل كانت مفيدة؟

المحلول 2

This isn't an ideal solution as it has to save the file as an image instead of using StringIO but it works.

    import Image as image
    from matplotlib.pyplot import figure
    from reportlab.pdfgen import canvas
    from reportlab.lib.utils import ImageReader

    can = canvas.Canvas()
    self.f = figure()
    self.a = self.f.add_subplot(2,1,1)
    self.a.plot(x,y)
    self.a2 =self.a.twinx()
    self.a2.plot(x,y2,'r')
    self.a2.set_ylabel(ylbl2,color='r')
    self.a.set_xlabel(xlbl)
    self.a.set_ylabel(ylbl,color='b')


    self.f.savefig('plot.png',format='png')
    image.open('plot.png').save('plot.png','PNG')   
    can.drawImage('plot.png',100,250, width=400,height=350)

نصائح أخرى

The key is that you must use plt.close() after you're done adding images. Here's a quick example that works for me using seaborn and barplot. Assume I have a dataframe with different data that I want plotted over a few figures.

import matplotlib.pyplot as plt
import seaborn as sns
import cStringIO
from reportlab.platypus import Image

my_df = <some dataframe>
cols_to_plot = <[specific columns to plot]>

plots = []

def create_barplot(col):
    sns_plot = sns.barplot(x='col1', y=col, hue='col2', data=my_df)
    imgdata = cStringIO.StringIO()
    sns_plot.figure.savefig(imgdata, format='png')
    imgdata.seek(0)
    plots.append(Image(imgdata))
    plt.close()                   # This is the key!!!

for col in cols_to_plot:
    create_barplot(col)

for barplot in plots:
    story.append(barplot)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top