将statsmodels结果保存为Python作为图像文件

问题描述:

我使用statsmodels来进行OLS估计。结果可以在控制台上使用print(results.summary())进行研究。我想存储与.png文件相同的表格。下面是一个带有可重复示例的片段。将statsmodels结果保存为Python作为图像文件

import pandas as pd 
import numpy as np 
import matplotlib.dates as mdates 
import statsmodels.api as sm 

# Dataframe with some random numbers 
np.random.seed(123) 
rows = 10 
df = pd.DataFrame(np.random.randint(90,110,size=(rows, 2)), columns=list('AB')) 
datelist = pd.date_range(pd.datetime(2017, 1, 1).strftime('%Y-%m-%d'), periods=rows).tolist() 
df['dates'] = datelist 
df = df.set_index(['dates']) 
df.index = pd.to_datetime(df.index) 
print(df) 

# OLS estimates using statsmodels.api 
x = df['A'] 
y = df['B'] 

model = sm.OLS(y,sm.add_constant(x)).fit() 

# Output 
print(model.summary()) 

enter image description here

我做了使用建议here有些幼稚的尝试,但我怀疑我远离目标:

os.chdir('C:/images') 
sys.stdout = open("model.png","w") 
print(model.summary()) 
sys.stdout.close() 

到目前为止,这只是提出了一个很长的错误信息。

谢谢你的任何建议!

这是一个非常不寻常的任务,你的方法有点疯狂。您试图将一个字符串(某些度量空间中没有位置)与某个图像(基于位置)组合在一起。

不管你做什么,你需要一些文本的渲染引擎!

我试图用pillow,但结果是丑陋的。可能是因为它非常有限,并且后处理消除锯齿功能不能保存任何内容。但也许我做错了什么。

from PIL import Image, ImageDraw, ImageFont 
image = Image.new('RGB', (800, 400)) 
draw = ImageDraw.Draw(image) 
font = ImageFont.truetype("arial.ttf", 16) 
draw.text((0, 0), str(model.summary()), font=font) 
image = image.convert('1') # bw 
image = image.resize((600, 300), Image.ANTIALIAS) 
image.save('output.png') 

当您使用statsmodels,我假设你已经有了。这个也可以使用。下面是一些方法,这是相当不错,虽然不是完美的(一些线路的变化,我不知道为什么; 编辑: OP管理使用等宽的字体,以修复这些):

import matplotlib.pyplot as plt 
plt.rc('figure', figsize=(12, 7)) 
#plt.text(0.01, 0.05, str(model.summary()), {'fontsize': 12}) old approach 
plt.text(0.01, 0.05, str(model.summary()), {'fontsize': 10}, fontproperties = 'monospace') # approach improved by OP -> monospace! 
plt.axis('off') 
plt.tight_layout() 
plt.savefig('output.png') 

输出:

enter image description here

编辑: OP管理使用等宽的字体以提高matplotlib的方法!我将它结合在这里,它反映在输出图像中。

以此作为演示并研究python的文本渲染选项。也许matplotlib的方法可以改进,但也许你需要使用像pycairoSome SO-discussion

备注:在我的系统上,您的代码确实会给出这些警告!

编辑:seems你可以问statsmodels一个乳胶表示。所以我推荐使用这个,可能写这个文件并使用子进程调用pdflatex或类似的东西(这里有一些similar approach)。 matplotlib也可以使用乳胶(但我不会测试它,因为我目前在windows上),但在这种情况下,我们需要以某种方式再次调整文本到窗口的比例(与例如给定一些A5格式的完整乳胶文档相比) 。

+0

谢谢!正如你所建议的那样,我会直接进入文本渲染选项,看看我能做些什么。 – vestland

+2

关于matplotlib的建议在我尝试使用等间隔字体时做了一些技巧:'plt.text(0.01,0.05,str(results1。summary()),{'fontsize':10},fontproperties ='monospace')'再次感谢! – vestland

+1

啊,非常好。与全乳胶相比,我仍然认为这种方法低于标准。但谁知道你需要什么。 matplotlib方法的缺点是像我一样手动调整。不过谢谢你提到的字体! – sascha