'Embedding an base64 encoded image into Dash Data Table

I am hoping to embed an image as a data:URI into a Dash Datatable as in the example below. I borrowed the embedding from this post. I am creating the images on the fly using another library not included in the code below. When I run the Dash server using

python app.py

I get a data table with the encoded string and not an image. I thought using the 'presentation': 'markdown' (in the columns section of the dash documentation) would work but unfortunately not.

I also tried wrapping the url in a dash html.Img component but that did not seem to work either.

Any help on this would be appreciated! Thank you

import dash
import dash_table
import pandas as pd


url1 = '![Hello World](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAAAUCAAAAAAVAxSkAAABrUlEQVQ4y+3TPUvDQBgH8OdDOGa+oUMgk2MpdHIIgpSUiqC0OKirgxYX8QVFRQRpBRF8KShqLbgIYkUEteCgFVuqUEVxEIkvJFhae3m8S2KbSkcFBw9yHP88+eXucgH8kQZ/jSm4VDaIy9RKCpKac9NKgU4uEJNwhHhK3qvPBVO8rxRWmFXPF+NSM1KVMbwriAMwhDgVcrxeMZm85GR0PhvGJAAmyozJsbsxgNEir4iEjIK0SYqGd8sOR3rJAGN2BCEkOxhxMhpd8Mk0CXtZacxi1hr20mI/rzgnxayoidevcGuHXTC/q6QuYSMt1jC+gBIiMg12v2vb5NlklChiWnhmFZpwvxDGzuUzV8kOg+N8UUvNBp64vy9q3UN7gDXhwWLY2nMC3zRDibfsY7wjEkY79CdMZhrxSqqzxf4ZRPXwzWJirMicDa5KwiPeARygHXKNMQHEy3rMopDR20XNZGbJzUtrwDC/KshlLDWyqdmhxZzCsdYmf2fWZPoxCEDyfIvdtNQH0PRkH6Q51g8rFO3Qzxh2LbItcDCOpmuOsV7ntNaERe3v/lP/zO8yn4N+yNPrekmPAAAAAElFTkSuQmCC)'

data = [['Item 1', url1], ['Item 2', url1]]

# Create the pandas DataFrame 
df = pd.DataFrame(data, columns = ['Name', 'Image']) 

app = dash.Dash(__name__)


app.layout = dash_table.DataTable(
    id='table',
    columns=[{"name": 'Name', "id": 'Name'},
    {
            'id': 'Image',
            'name': 'Image',
            'presentation': 'markdown',
        },
    ],
    #fixed_columns={ 'headers': True, 'data': 1 },
    data=df.to_dict('records'),

)

if __name__ == '__main__':
    app.run_server(debug=True)


Solution 1:[1]

Looks like adding an assets folder locally and dumping image files in it works with respect to display

If I replace the url1 line in the above code with something like the following:

url1 = '![myImage-1](assets/test.png)'

Ressources should be placed in a specified assets folder as described here. Example:

app = dash.Dash(__name__, assets_folder='assets')

Note: assets_folder='assets' is the default value. See also this from the api reference:

assets_folder

a path, relative to the current working directory, for extra files to be used in the browser. Default 'assets'. All .js and .css files will be loaded immediately unless excluded by assets_ignore, and other files such as images will be served if requested.

An image will display in each row of the table. Ideally the data uri would work and I would prefer that approach, but I figured I would post this for now as a potential answer.

Solution 2:[2]

For dash==1.21.0, the markdown_options parameter can fix this problem if you specify the image with an HTML tag. Unfortunately, this solution also creates an XSS vulnerability according to the DataTable docs.

Code:

import dash
import dash_table

# base64 image string
img = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAAAUCAAAAAAVAxSkAAABrUlEQVQ4y+3TPUvDQBgH8OdDOGa+oUMgk2MpdHIIgpSUiqC0OKirgxYX8QVFRQRpBRF8KShqLbgIYkUEteCgFVuqUEVxEIkvJFhae3m8S2KbSkcFBw9yHP88+eXucgH8kQZ/jSm4VDaIy9RKCpKac9NKgU4uEJNwhHhK3qvPBVO8rxRWmFXPF+NSM1KVMbwriAMwhDgVcrxeMZm85GR0PhvGJAAmyozJsbsxgNEir4iEjIK0SYqGd8sOR3rJAGN2BCEkOxhxMhpd8Mk0CXtZacxi1hr20mI/rzgnxayoidevcGuHXTC/q6QuYSMt1jC+gBIiMg12v2vb5NlklChiWnhmFZpwvxDGzuUzV8kOg+N8UUvNBp64vy9q3UN7gDXhwWLY2nMC3zRDibfsY7wjEkY79CdMZhrxSqqzxf4ZRPXwzWJirMicDa5KwiPeARygHXKNMQHEy3rMopDR20XNZGbJzUtrwDC/KshlLDWyqdmhxZzCsdYmf2fWZPoxCEDyfIvdtNQH0PRkH6Q51g8rFO3Qzxh2LbItcDCOpmuOsV7ntNaERe3v/lP/zO8yn4N+yNPrekmPAAAAAElFTkSuQmCC"

# add html
img = f"<img src={img}>"

# make app
data = [{"Image": img, "Text": "test"}]

app = dash.Dash(__name__)
app.layout = dash_table.DataTable(
    columns=[
        {"id": name, "name": name, "presentation": "markdown"}
        for name in data[0]
    ],
    data=data,
    markdown_options={"html": True}  # dangerous but works
)

if __name__ == "__main__":
    app.run_server(debug=True)

Dash app screenshot:

Dash app screenshot

Another alternative is to use bootstrap: apparently it's much easier to display an image in a table with dbc rather than dash_table.

Solution 3:[3]

(NOTE: Please take into consideration that this approach leaves you open to an XSS vulnerability)

I've had the same problem which I've now managed to solve (One thing to note, I'm doing this using the Django framework, but it shouldn't matter).

My approach was to create a list of dicts (in a variable called columns_format, you can call it whatever you want) where I defined the column names and id, and in the dict (where the id is equal to ‘icons’, again yours can be called something different) is where you must first insert the parameter presentation and equal it to ‘markdown’.

columns_format = [
    dict(id = 'icons', name = '', presentation='markdown'),
    dict(id = 'symbol', name='Symbol'),
    dict(id = 'name', name='Coins'),

Once you have specified your columns in the columns_format variable you must then set the markdown_options parameter to ‘html’: True, and then set the columns parameter equal to the columns_format variable created earlier.

app.layout = dash_table.DataTable(
    markdown_options = {
        'html': True
    },
    data = coins_df,
    columns = columns_format,
)

What must happen (incase you are referencing an image from a link is to write it in a html format as below:

<img src="https://cdn.coinranking.com/bOabBYkcX/bitcoin_btc.svg" style="height: 30px; width:30px;"/>

So in each column where you want the images to appear must be in the above html format (height and width optional but recommended)

My dash DataTable below has the icons/images of Crypto Currency besides their symbol referencing a url for the location of the icons/images.

images in dash data table

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Pascal
Solution 2 Ryan Park
Solution 3 DharmanBot