Insert matplotlib images into a pandas dataframe

喜欢而已 提交于 2019-11-28 11:37:26

What you see as Figure (200x200) is the __repr__ string of the matplotlib Figure class. It is the text representation of that python object (the same that you would see when doing print(fig)).

What you want instead is to have an actual image in the table. An easy option would be to save the matplotlib figure as png image, create an html tag, <img src="some.png" /> and hence show the table.

import pandas as pd
import numpy as np;np.random.seed(1)
import matplotlib.pyplot as plt
import matplotlib.colors

df = pd.DataFrame({"info" : np.random.randint(0,10,10), 
                   "status" : np.random.randint(0,3,10)})

cmap = matplotlib.colors.ListedColormap(["crimson","orange","limegreen"])

def createFigure(i):
    fig, ax = plt.subplots(figsize=(.4,.4))
    fig.subplots_adjust(0,0,1,1)
    ax.axis("off")
    ax.axis([0,1,0,1])
    c = plt.Circle((.5,.5), .4, color=cmap(i))
    ax.add_patch(c)
    ax.text(.5,.5, str(i), ha="center", va="center")
    return fig

def mapping(i):
    fig = createFigure(i)
    fname = "data/map_{}.png".format(i)
    fig.savefig(fname)
    imgstr = '<img src="{}" /> '.format(fname)
    return imgstr


df['image'] = df['status'].map(mapping)
df.to_html('test.html', escape=False)

The drawback of this is that you have a lot of images saved somewhere on disk. If this is not desired, you may store the image encoded as base64 in the html file, <img src="data:image/png;base64,iVBORw0KGgoAAAAN..." />.

import pandas as pd
import numpy as np;np.random.seed(1)
import matplotlib.pyplot as plt
import matplotlib.colors
from io import BytesIO
import base64

df = pd.DataFrame({"info" : np.random.randint(0,10,10), 
                   "status" : np.random.randint(0,3,10)})

cmap = matplotlib.colors.ListedColormap(["crimson","orange","limegreen"])

def createFigure(i):
    fig, ax = plt.subplots(figsize=(.4,.4))
    fig.subplots_adjust(0,0,1,1)
    ax.axis("off")
    ax.axis([0,1,0,1])
    c = plt.Circle((.5,.5), .4, color=cmap(i))
    ax.add_patch(c)
    ax.text(.5,.5, str(i), ha="center", va="center")
    return fig

def fig2inlinehtml(fig,i):
    figfile = BytesIO()
    fig.savefig(figfile, format='png')
    figfile.seek(0) 
    figdata_png = base64.b64encode(figfile.getvalue())
    imgstr = '<img src="data:image/png;base64,{}" />'.format(figdata_png)
    return imgstr

def mapping(i):
    fig = createFigure(i)
    return fig2inlinehtml(fig,i)


with pd.option_context('display.max_colwidth', -1):
    df.to_html('test.html', escape=False, formatters=dict(status=mapping))

The output looks the same, but there are no images saved to disk.

This also works nicely in a Jupyter Notebook, with a small modification,

from IPython.display import HTML
# ...
pd.set_option('display.max_colwidth', -1)
HTML(df.to_html(escape=False, formatters=dict(status=mapping)))

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!