これは役に立たない機能のように思われるかもしれませんが、私にとっては非常に役立ちます。 CanopyIDE内で取得した出力を保存したいと思います。これはキャノピーに固有のものではないと思いますが、わかりやすくするために使用しています。たとえば、私のコンソールOut [2]は、これから欲しいものです。
フォーマットはとてもいいと思います。出力を保存するだけでなく、毎回これを再現するのは時間の無駄です。だから私の質問は、どうすればこの数字を把握できるのかということです。理想的には、実装は標準的な方法と同様であり、次のように実行できます。
from matplotlib.backends.backend_pdf import PdfPages
pp = PdfPages('Output.pdf')
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
df.plot(how='table')
pp.savefig()
pp.close()
注:以前に非常によく似た質問があったことを認識しています( Pandasデータフレーム/シリーズデータを図として保存する方法? ))が、回答を受け取ったことはありませんそして、私は質問をより明確に述べたと思います。
これはややハックな解決策ですが、それで仕事は終わります。 .pdfが必要でしたが、ボーナス.pngが表示されます。 :)
import numpy as np
import pandas as pd
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
from PySide.QtGui import QImage
from PySide.QtGui import QPainter
from PySide.QtCore import QSize
from PySide.QtWebKit import QWebPage
arrays = [np.hstack([ ['one']*3, ['two']*3]), ['Dog', 'Bird', 'Cat']*2]
columns = pd.MultiIndex.from_arrays(arrays, names=['foo', 'bar'])
df =pd.DataFrame(np.zeros((3,6)),columns=columns,index=pd.date_range('20000103',periods=3))
h = "<!DOCTYPE html> <html> <body> <p> " + df.to_html() + " </p> </body> </html>";
page = QWebPage()
page.setViewportSize(QSize(5000,5000))
frame = page.mainFrame()
frame.setHtml(h, "text/html")
img = QImage(1000,700, QImage.Format(5))
Painter = QPainter(img)
frame.render(Painter)
Painter.end()
a = img.save("html.png")
pp = PdfPages('html.pdf')
fig = plt.figure(figsize=(8,6),dpi=1080)
ax = fig.add_subplot(1, 1, 1)
img2 = plt.imread("html.png")
plt.axis('off')
ax.imshow(img2)
pp.savefig()
pp.close()
編集を歓迎します。
IDEがレンダリングしているのはHTMLテーブルだと思います。これは、ipythonノートブックが行うことです。
あなたはこうしてそれへのハンドルを得ることができます:
from IPython.display import HTML
import pandas as pd
data = pd.DataFrame({'spam':['ham','green','five',0,'kitties'],
'eggs':[0,1,2,3,4]})
h = HTML(data.to_html())
h
hTMLファイルに保存します。
my_file = open('some_file.html', 'w')
my_file.write(h.data)
my_file.close()
ここで必要なのは、pdfに出力されたグラフの中でテーブルをpdfファイルに出力する一貫した方法だと思います。
私の最初の考えは、matplotlibバックエンドを使用しないことです。
from matplotlib.backends.backend_pdf import PdfPages
書式設定オプションがいくらか制限されているように見え、テーブルを画像として書式設定することに傾いていたためです(したがって、テーブルのテキストを選択できない形式でレンダリングします)
Matplotlib pdfバックエンドを使用せずにデータフレーム出力とmatplotlibプロットをpdfに混在させたい場合は、2つの方法が考えられます。
まず、xhtml2pdf
ライブラリをインストールします。これは少しパッチが適用されているように見えますが、 Githubでアクティブ であり、いくつかの 基本的な使用法のドキュメントはこちら です。 pip
、つまりpip install xhtml2pdf
からインストールできます
それが済んだら、matplotlibの図、テーブル(すべてテキストを選択可能)、別の図を埋め込んだベアボーンの例を次に示します。 CSSなどをいじって、フォーマットを正確な仕様に変更することができますが、これで簡単に説明できると思います。
from xhtml2pdf import pisa # this is the module that will do the work
import numpy as np
import pandas as pd
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
# Utility function
def convertHtmlToPdf(sourceHtml, outputFilename):
# open output file for writing (truncated binary)
resultFile = open(outputFilename, "w+b")
# convert HTML to PDF
pisaStatus = pisa.CreatePDF(
sourceHtml, # the HTML to convert
dest=resultFile, # file handle to recieve result
path='.') # this path is needed so relative paths for
# temporary image sources work
# close output file
resultFile.close() # close output file
# return True on success and False on errors
return pisaStatus.err
# Main program
if __name__=='__main__':
arrays = [np.hstack([ ['one']*3, ['two']*3]), ['Dog', 'Bird', 'Cat']*2]
columns = pd.MultiIndex.from_arrays(arrays, names=['foo', 'bar'])
df = pd.DataFrame(np.zeros((3,6)),columns=columns,index=pd.date_range('20000103',periods=3))
# Define your data
sourceHtml = '<html><head>'
# add some table CSS in head
sourceHtml += '''<style>
table, td, th {
border-style: double;
border-width: 3px;
}
td,th {
padding: 5px;
}
</style>'''
sourceHtml += '</head><body>'
#Add a matplotlib figure(s)
plt.plot(range(20))
plt.savefig('tmp1.jpg')
sourceHtml += '\n<p><img src="tmp1.jpg"></p>'
# Add the dataframe
sourceHtml += '\n<p>' + df.to_html() + '</p>'
#Add another matplotlib figure(s)
plt.plot(range(70,100))
plt.savefig('tmp2.jpg')
sourceHtml += '\n<p><img src="tmp2.jpg"></p>'
sourceHtml += '</body></html>'
outputFilename = 'test.pdf'
convertHtmlToPdf(sourceHtml, outputFilename)
注執筆時点でxhtml2pdfにバグがあるようです。つまり、一部のCSSは尊重されていません。この質問に特に関係するのは、テーブルの周りに二重の境界線を付けることは不可能のように思われるということです
回答のコメントで、一部のユーザー(少なくとも、回答と賞金の両方を授与した@Keith!)は、テーブルを選択可能にすることを望んでいることが明らかになりましたが、間違いなくmatplotlib軸上にあります。これは、元の方法にいくらか一致しています。したがって、これはmatplotlibオブジェクトとmatplotlibオブジェクトにのみpdf
バックエンドを使用するメソッドです。テーブルの見栄えはあまり良くないと思います。特に階層列ヘッダーの表示はそうですが、それは選択の問題だと思います。 この回答 と、テーブル表示用に軸をフォーマットする方法についてのコメントに感謝します。
import numpy as np
import pandas as pd
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
# Main program
if __name__=='__main__':
pp = PdfPages('Output.pdf')
arrays = [np.hstack([ ['one']*3, ['two']*3]), ['Dog', 'Bird', 'Cat']*2]
columns = pd.MultiIndex.from_arrays(arrays, names=['foo', 'bar'])
df =pd.DataFrame(np.zeros((3,6)),columns=columns,index=pd.date_range('20000103',periods=3))
plt.plot(range(20))
pp.savefig()
plt.close()
# Calculate some sizes for formatting - constants are arbitrary - play around
nrows, ncols = len(df)+1, len(df.columns) + 10
hcell, wcell = 0.3, 1.
hpad, wpad = 0, 0
#put the table on a correctly sized figure
fig=plt.figure(figsize=(ncols*wcell+wpad, nrows*hcell+hpad))
plt.gca().axis('off')
matplotlib_tab = pd.tools.plotting.table(plt.gca(),df, loc='center')
pp.savefig()
plt.close()
#Add another matplotlib figure(s)
plt.plot(range(70,100))
pp.savefig()
plt.close()
pp.close()