6

I'm in the process of evaluating python plotly and/or dash as an alternative to bokeh/holoviews for linked plots that update images.

Requirements: linking data point to image: I have scatter plots and heatmaps in which individual data points represent values derived from images. I would like to link back from a data point in a scatterplot to the image that the numerical value for this data point was derived from. The image data is in a numpy array or can be provided by a callback function. I would like to avoid writing a .png file to disk and embedding the png file in a html element.

linking image selections to data points: e.g. Display an image. Update a plot according to the selection in the image (e.g. a simple histogram).

However, I can't seem to find any widget for image display in plotly/dash. Am I missing something or is there really no such thing?

2 Answers 2

2

I would like to link back from a data point in a scatterplot to the image that the numerical value for this data point was derived from.

See https://plot.ly/dash/interactive-graphing. You can assign a callback to selectedData, hoverData, or clickData property of the dash_core_components.Graph.

linking image selections to data points: e.g. Display an image. Update a plot according to the selection in the image (e.g. a simple histogram).

You could display a background image on a plotly graph and then use the same selectedData tools to update callbacks based off of the selected region. Here is a simple example:

import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import base64
import json

app = dash.Dash()
app.css.append_css({'external_url': 'https://codepen.io/chriddyp/pen/dZVMbK.css'})

RANGE = [0, 1]

def InteractiveImage(id, image_path):
    encoded_image = base64.b64encode(open(image_path, 'rb').read())
    return dcc.Graph(
        id=id,
        figure={
            'data': [],
            'layout': {
                'xaxis': {
                    'range': RANGE
                },
                'yaxis': {
                    'range': RANGE,
                    'scaleanchor': 'x',
                    'scaleratio': 1
                },
                'height': 600,
                'images': [{
                    'xref': 'x',
                    'yref': 'y',
                    'x': RANGE[0],
                    'y': RANGE[1],
                    'sizex': RANGE[1] - RANGE[0],
                    'sizey': RANGE[1] - RANGE[0],
                    'sizing': 'stretch',
                    'layer': 'below',
                    'source': 'data:image/png;base64,{}'.format(encoded_image)
                }],
                'dragmode': 'select'  # or 'lasso'
            }
        }
    )


app.layout = html.Div([
    html.Div(className='row', children=[
        html.Div(InteractiveImage('image', 'dash_app.png'), className='six columns'),
        html.Div(dcc.Graph(id='graph'), className='six columns')
    ]),
    html.Pre(id='console')
])


# display the event data for debugging
@app.callback(Output('console', 'children'), [Input('image', 'selectedData')])
def display_selected_data(selectedData):
    return json.dumps(selectedData, indent=2)


@app.callback(Output('graph', 'figure'), [Input('image', 'selectedData')])
def update_histogram(selectedData):
    x_range = selectedData['range']['x']
    x_range = selectedData['range']['y']
    # filter data based off of selection in here

    # for simple example purposes, we'll just display the selected RANGE
    return {
        'data': [{
            'x': x_range,
            'y': x_range,
            'mode': 'markers',
            'marker': {
                'size': 20
            }
        }],
        'layout': {
            'xaxis': {'range': RANGE},
            'yaxis': {'range': RANGE, 'scaleanchor': 'x', 'scaleratio': 1},
            'height': 600
        }
    }


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

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks very much for the detailed example. However it appears that this requires rendering the raster data that I might have in a numpy array for example into an image file (e.g. a .png). If I want to apply a look-up-table for example, I would have to save a transformed version of the data again. I guess I'm looking for something that is more like a matplotlib imshow type raster image visualization widget.
0

If you are still interested in the answer:https://plotly.com/python/imshow/, if you scroll to the bottom, you will see how to apply it to Dash

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.