在ReportLab中绘制多个matplotlib图表

0 投票
2 回答
4098 浏览
提问于 2025-04-18 01:45

我正在尝试把一个matplotlib图表放到reportlab的画布上。我可以用这个问题中的代码画一个简单的图表:如何在reportlab画布上绘制matplotlib图形? 但是当我尝试使用子图或者多个图表时,它就不能正常工作。这样做会导致同样的图像被绘制两次,即使我添加了像imgdata.close()或者删除图形这样的代码:

    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)

在尝试使用子图时,它只是产生了一个空白的图表,我不知道该怎么处理:

    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)

如果能对此问题提供任何解决方案或建议,我将非常感激。

2 个回答

1

关键是,在你完成添加图片后,一定要使用 plt.close()。下面是一个简单的例子,使用了seaborn和条形图,效果很好。假设我有一个数据表,里面有不同的数据,我想把这些数据绘制成几幅图。

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)
0

这不是一个最理想的解决办法,因为它需要把文件保存为图片,而不是使用StringIO,但它确实能工作。

    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)

撰写回答