Export a Pandas Dataframe as a Table Image

How to save a pandas DataFrame table as a png

Pandas allows you to plot tables using matplotlib (details here).
Usually this plots the table directly onto a plot (with axes and everything) which is not what you want. However, these can be removed first:

import matplotlib.pyplot as plt
import pandas as pd
from pandas.table.plotting import table # EDIT: see deprecation warnings below

ax = plt.subplot(111, frame_on=False) # no visible frame
ax.xaxis.set_visible(False) # hide the x axis
ax.yaxis.set_visible(False) # hide the y axis

table(ax, df) # where df is your data frame

plt.savefig('mytable.png')

The output might not be the prettiest but you can find additional arguments for the table() function here.
Also thanks to this post for info on how to remove axes in matplotlib.


EDIT:

Here is a (admittedly quite hacky) way of simulating multi-indexes when plotting using the method above. If you have a multi-index data frame called df that looks like:

first  second
bar one 1.991802
two 0.403415
baz one -1.024986
two -0.522366
foo one 0.350297
two -0.444106
qux one -0.472536
two 0.999393
dtype: float64

First reset the indexes so they become normal columns

df = df.reset_index() 
df
first second 0
0 bar one 1.991802
1 bar two 0.403415
2 baz one -1.024986
3 baz two -0.522366
4 foo one 0.350297
5 foo two -0.444106
6 qux one -0.472536
7 qux two 0.999393

Remove all duplicates from the higher order multi-index columns by setting them to an empty string (in my example I only have duplicate indexes in "first"):

df.ix[df.duplicated('first') , 'first'] = '' # see deprecation warnings below
df
first second 0
0 bar one 1.991802
1 two 0.403415
2 baz one -1.024986
3 two -0.522366
4 foo one 0.350297
5 two -0.444106
6 qux one -0.472536
7 two 0.999393

Change the column names over your "indexes" to the empty string

new_cols = df.columns.values
new_cols[:2] = '','' # since my index columns are the two left-most on the table
df.columns = new_cols

Now call the table function but set all the row labels in the table to the empty string (this makes sure the actual indexes of your plot are not displayed):

table(ax, df, rowLabels=['']*df.shape[0], loc='center')

et voila:

Sample Image

Your not-so-pretty but totally functional multi-indexed table.

EDIT: DEPRECATION WARNINGS

As pointed out in the comments, the import statement for table:

from pandas.tools.plotting import table

is now deprecated in newer versions of pandas in favour of:

from pandas.plotting import table 

EDIT: DEPRECATION WARNINGS 2

The ix indexer has now been fully deprecated so we should use the loc indexer instead. Replace:

df.ix[df.duplicated('first') , 'first'] = ''

with

df.loc[df.duplicated('first') , 'first'] = ''

How to save the Pandas dataframe/series data as a figure?

Option-1: use matplotlib table functionality, with some additional styling:

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

df = pd.DataFrame()
df['date'] = ['2016-04-01', '2016-04-02', '2016-04-03']
df['calories'] = [2200, 2100, 1500]
df['sleep hours'] = [8, 7.5, 8.2]
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 mpl_table._cells.items():
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.get_figure(), ax

fig,ax = render_mpl_table(df, header_columns=0, col_width=2.0)
fig.savefig("table_mpl.png")

Sample Image

Options-2 Use Plotly + kaleido

import plotly.figure_factory as ff
import pandas as pd

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

fig = ff.create_table(df)
fig.update_layout(
autosize=False,
width=500,
height=200,
)
fig.write_image("table_plotly.png", scale=2)
fig.show()

Sample Image

For the above, the font size can be changed using the font attribute:

fig.update_layout(
autosize=False,
width=500,
height=200,
font={'size':8}
)

Exporting a python dataframe + text element to an image

You can add the line df.index.name = pd.Timestamp('now').replace(microsecond=0) to add the timestamp on the first row:

Sample Image

To add the line you can use .style.set_table_styles:

data = {'Type': ['Type 1', 'Type 2', 'Type 3'], 'Value': [20, 21, 19]}
df = pd.DataFrame(data)
df.index.name = pd.Timestamp('now').replace(microsecond=0)
df.loc[len(df)] = ['Total',df['Value'].sum()]
test = df.style.set_table_styles([{'selector' : '.row3','props' : [('border-top','3px solid black')]}])
dfi.export(test, 'table.png')

Sample Image

Pandas - How to Save A Styled Dataframe to Image

Was able to change how I was using dataframe-image on the styler object and got it working. Passing it into the export() function rather than calling it off the object directly seems to be the right way to do this.

The .render() did get the HTML but was often losing much of the styling when converting it to image or when not viewed with Ipython HTML display. See comparision below.
Sample Image

Working Code:

import pandas as pd
import numpy as np
import dataframe_image as dfi

col_name = 'TestColumn'

temp_df = pd.DataFrame({'TestColumn':['A','B','A',np.nan]})

t1 = (temp_df[col_name].fillna("Unknown").value_counts()/len(temp_df)*100).to_frame().reset_index()
t1.rename(columns={'index':' '}, inplace=True)
t1[' '] = t1[' '].astype(str)

style_test = t1.style.bar(subset=[col_name], color='#5e81f2', vmax=100, vmin=0).set_table_attributes('style="font-size: 17px"').set_properties(
**{'color': 'black !important',
'border': '1px black solid !important'}
).set_table_styles([{
'selector': 'th',
'props': [('border', '1px black solid !important')]
}]).set_properties( **{'width': '500px'}).hide_index().set_properties(subset=[" "], **{'text-align': 'left'})

dfi.export(style_test, 'successful_test.png')

Option for dataframe-image module (convert a styled DataFrame to image) that the creator stopped updating and supporting

You could use pandas .to_html(), then use imgkit to write to file.

import pandas as pd
import imgkit

def csv_to_image(csv_file,name_file):
df = pd.read_csv(csv_file)

df = df.style.set_table_styles([dict(selector='th', props=[('text-align', 'center'),('background-color', '#40466e'),('color', 'white')])])
df.set_properties(**{'text-align': 'center'}).hide(axis='index')
pd.set_option('colheader_justify', 'center')

html = df.to_html()
imgkit.from_string(html, name_file + ".png")

Can I save a table/dataframe to a file (like png/jpg) in python?

Assuming this table is a pandas DataFrame, this library might help:

www.dexplo.org/dataframe_image/

This library would export pandas DataFrames in a jupyter notebook fashioned way.

Example usage:

import pandas as pd
import dataframe_image as dfi
df = pd.DataFrame({'key':[1,2,3],'val':['a','b','c']})
dfi.export(df, 'dataframe.png')

Sample Image



Related Topics



Leave a reply



Submit