58

Is it possible to export a Pandas dataframe as an image file? Something like df.to_png() or df.to_table().savefig('table.png').

At the moment I export a dataframe using df.to_csv(). I then open this csv file in Excel to make the data look pretty and then copy / paste the Excel table into Powerpoint as an image. I see matplotlib has a .table() method, but I'm having trouble getting it to work with my df.

The data frame I'm using has 5 columns and 5 rows and each 'cell' is a number.

nbro
  • 15,395
  • 32
  • 113
  • 196
user2370852
  • 580
  • 1
  • 5
  • 5
  • Does this answer your question? [How to save a pandas DataFrame table as a png](https://stackoverflow.com/questions/35634238/how-to-save-a-pandas-dataframe-table-as-a-png) – Tomerikoo Nov 10 '21 at 08:43

4 Answers4

64

With some additional code, you can even make output look decent:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import six

df = pd.DataFrame()
df['date'] = ['2016-04-01', '2016-04-02', '2016-04-03']
df['calories'] = [2200, 2100, 1500]
df['sleep hours'] = [2200, 2100, 1500]
df['gym'] = [True, False, False]


def render_mpl_table(data, col_width=3.0, row_height=0.625, font_size=14,
                     header_color='#40466e', row_colors=['#f1f1f2', 'w'], edge_color='w',
                     bbox=[0, 0, 1, 1], header_columns=0,
                     ax=None, **kwargs):
    if ax is None:
        size = (np.array(data.shape[::-1]) + np.array([0, 1])) * np.array([col_width, row_height])
        fig, ax = plt.subplots(figsize=size)
        ax.axis('off')

    mpl_table = ax.table(cellText=data.values, bbox=bbox, colLabels=data.columns, **kwargs)

    mpl_table.auto_set_font_size(False)
    mpl_table.set_fontsize(font_size)

    for k, cell in  six.iteritems(mpl_table._cells):
        cell.set_edgecolor(edge_color)
        if k[0] == 0 or k[1] < header_columns:
            cell.set_text_props(weight='bold', color='w')
            cell.set_facecolor(header_color)
        else:
            cell.set_facecolor(row_colors[k[0]%len(row_colors) ])
    return ax

render_mpl_table(df, header_columns=0, col_width=2.0)

enter image description here

volodymyr
  • 7,256
  • 3
  • 42
  • 45
  • I get the error `ImportError: No module named externals`. – Alex F May 17 '17 at 19:48
  • six is in standard library. I've adjusted the answer. It should work now- thanks for pointing. It is to write Python 2 and Python 3 compatible code. Do you need Python 3 only? – volodymyr May 18 '17 at 10:06
  • This is nice. But how do we save to an actual file..? – zerohedge Dec 03 '17 at 00:27
  • 1
    @zerohedge I modified the function in this answer to spit out the ax and fig, and used fig.savefig() – Luc Gendrot Dec 05 '17 at 02:02
  • 2
    While you can, of course, output fig and save image inside a function, it is generally advisable to make function do one and only one thing. Saving a figure is different from making a figure - there are format options, dpi settings, etc. In our setup, saving to .png (and adding those .png-s into google slides) are handled by a different method. Moreover, you can always get a figure from axis `ax.get_figure()`, so outputting both is redundant (however can be convenient, so you don't need to call `ax.get_figure()` ). – volodymyr Dec 05 '17 at 08:24
  • Thank you @volodymyr for this helpful answer – Ammar Alyousfi Dec 09 '18 at 09:28
  • 2
    This is a great answer @volodymyr thanks very muhc. Is there anyway to have columns "autofit" according to their length? Thanks – SOK Jun 10 '20 at 05:22
  • @LucGendrot when I execute your code in Jupyter notebook it is show table while in Pycharm it is not shown also to download the table where exactly should I place the code **fig.savefig('exampleimage.png'**) – Jainmiah Sep 14 '20 at 16:25
32

If you have pdflatex and imagemagick installed, you could export the DataFrame to tex, use pdflatex to convert it to a pdf file, and then convert the pdf to png using imagemagick:

import pandas as pd
import numpy as np
import subprocess

df = pd.DataFrame({'d': [1., 1., 1., 2., 2., 2.],
                   'c': np.tile(['a', 'b', 'c'], 2),
                   'v': np.arange(1., 7.)})
filename = 'out.tex'
pdffile = 'out.pdf'
outname = 'out.png'

template = r'''\documentclass[preview]{{standalone}}
\usepackage{{booktabs}}
\begin{{document}}
{}
\end{{document}}
'''

with open(filename, 'wb') as f:
    f.write(template.format(df.to_latex()))

subprocess.call(['pdflatex', filename])
subprocess.call(['convert', '-density', '300', pdffile, '-quality', '90', outname])

enter image description here

If you install phantomjs and imagemagick, you could export the DataFrame to HTML and then use phantomjs to convert the HTML to png, and imagemagick to crop the result:

import pandas as pd
import numpy as np
import subprocess

df = pd.DataFrame({'d': [1., 1., 1., 2., 2., 2.],
                   'c': np.tile(['a', 'b', 'c'], 2),
                   'v': np.arange(1., 7.)})
filename = '/tmp/out.html'
outname = '/tmp/out.png'
cropname = '/tmp/cropped.png'

with open(filename, 'wb') as f:
    f.write(df.to_html())
rasterize = '/path/to/phantomjs/examples/rasterize.js'
subprocess.call(['phantomjs', rasterize, filename, outname])
subprocess.call(['convert', outname, '-trim', cropname])

enter image description here

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
9

You could take a look at the dataframe-image package (https://pypi.org/project/dataframe-image/), which offers the possibility to export a (styled) dataframe as an image file. An example of how this can be achieved is shown in the image below (which I copied from the above mentioned webpage).

enter image description here

5

I had the same requirement for a project I am doing. But none of the answers came elegant to my requirement. Here is something which finally helped me, and might be useful for this case:

from bokeh.io import export_png, export_svgs
from bokeh.models import ColumnDataSource, DataTable, TableColumn

def save_df_as_image(df, path):
    source = ColumnDataSource(df)
    df_columns = [df.index.name]
    df_columns.extend(df.columns.values)
    columns_for_table=[]
    for column in df_columns:
        columns_for_table.append(TableColumn(field=column, title=column))

    data_table = DataTable(source=source, columns=columns_for_table,height_policy="auto",width_policy="auto",index_position=None)
    export_png(data_table, filename = path)

enter image description here

raghavsikaria
  • 867
  • 17
  • 30