在ReportLab中绘制多个matplotlib图表
我正在尝试把一个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)