Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show a local image in an interactive dash with python

So I am working on Dash Plotly. The webpage should have a text box and a button. The idea is that when I write an image name and then select the button, it will show the image from a local directory.

I tried to divide the whole work into 2 parts.

First, I have this code which shows you whatever you write in the text box and click the button. The code:

# -*- coding: utf-8 -*-
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import os 
from PIL import Image
import numpy as np
import plotly.express as px

os.chdir(os.path.dirname(os.path.abspath(__file__)))

external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(
    [
        html.I("Try typing the image name in input and observe it"),
        html.Br(),
        dcc.Input(id="input", type="text", placeholder=""),
        html.Div(id="output"),
    ]
)


@app.callback(
    Output("output", "children"),
    Input("input", "value")
)
def update_output(input):
    return u'Input {}'.format(input)


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

Next, I have this code which when run locally, just shows you the image in the webpage. Point: the python file and the image are in same local directory. The code:

import os 

from PIL import Image
import numpy as np
import plotly.express as px

# Change working dir to current running script dir:
print('[change directory]')
os.chdir(os.path.dirname(os.path.abspath(__file__)))

def test():
    # load the image
    img = np.array(Image.open('img name.tiff'))

    fig = px.imshow(img, color_continuous_scale='gray')
    fig.update_layout(coloraxis_showscale=False)
    fig.update_xaxes(showticklabels=False)
    fig.update_yaxes(showticklabels=False)
    fig.show()

test()

Now, I need a way to add these 2 codes so that when I write 'img name.tiff' in the text box and select the button, it will show me the picture in the webpage.

I am very new in Dash and Plotly. I have no idea how to do it. I tried to study it but could not find anything helpful. Can anyone help?

like image 904
Khabbab Zakaria Avatar asked Oct 24 '25 09:10

Khabbab Zakaria


1 Answers

You could change your callback to something like this:

@app.callback(Output("output", "children"), Input("input", "value"))
def update_output(input):
    if not input:
        raise PreventUpdate

    try:
        img = np.array(Image.open(f"assets/{input}"))
    except OSError:
        raise PreventUpdate

    fig = px.imshow(img, color_continuous_scale="gray")
    fig.update_layout(coloraxis_showscale=False)
    fig.update_xaxes(showticklabels=False)
    fig.update_yaxes(showticklabels=False)

    return dcc.Graph(figure=fig)

If there's no input value or the image with the user specified path can't be opened, we use PreventUpdate:

In certain situations, you don't want to update the callback output. You can achieve this by raising a PreventUpdate exception in the callback function.

Note: this example assumes the image is stored in the assets folder.

Update: Implementation using button

@app.callback(
    Output("output", "children"),
    Input("input", "value"),
    Input("show-image", "n_clicks"),
    prevent_initial_call=True,
)
def update_output(input, n_clicks):
    if not input:
        raise PreventUpdate

    ctx = dash.callback_context
    if ctx.triggered[0]["prop_id"].split(".")[0] != "show-image":
        raise PreventUpdate

    try:
        img = np.array(Image.open(f"assets/{input}"))
    except OSError:
        raise PreventUpdate

    fig = px.imshow(img, color_continuous_scale="gray")
    fig.update_layout(coloraxis_showscale=False)
    fig.update_xaxes(showticklabels=False)
    fig.update_yaxes(showticklabels=False)

    return dcc.Graph(figure=fig)

In the previous example on finding an image that can be opened the callback returns the graph with the image. If you want to defer showing the image until a button is clicked you can add a button to the layout

html.Button("Show Image", id="show-image", n_clicks=0)

and use callback_context to determine which Input triggered the button. If the id of this input equals "show-input" (the id of our button) we show the graph and image.

like image 160
Bas van der Linden Avatar answered Oct 27 '25 01:10

Bas van der Linden



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!