Update title after clicking / hovering on data point

I want to update (the title of) this graph:

def update_zoom_chart(df5, device_name):

    fig_zoom = px.scatter(df5
                              , x = "time"
                              , y = 'value'
                              , color = 'variable'
                              , symbol = 'variable'
                              , opacity = 0.5
                              , template = 'plotly_dark'
                              , title = "%s <br><sup>Data of a single error chosen from above graph</sup>" % (device_name)
                              )
    fig_zoom.update_traces(marker = dict(
                                            size = 5
                                            )
                           )
    fig_zoom.update_layout(
                              transition_duration = 500
                              , autosize = True
                              , height = 600
                              , hovermode='x unified'
                              )
    return fig_zoom

which is working (except of the title update) via:

@app.callback(
              Output("Zoomed", "figure"), 
              Input('General', 'clickData')
              )
def update_hover(clickData):
    if clickData:
        path = clickData['points'][0]['hovertext']
        df5 = df2[df2['Path'] == path]
        device_name = df5['Device'][0]
        return update_zoom_chart(df5, device_name)
    else:
        df5 = df2[df2['Path']== df2['Path'].iloc[0]]
        device_name = df5['Device'][0]
        return update_zoom_chart(df5, device_name)

What I wonder is that it is working in the very first instance (so the else condition seems to work) but when I click on a data point which makes the graph to be updated via the the if-condition, the title update is not working. I receive a quite long list of error which is (to me) very non-specific but the very last line is:

line 3631, in get_loc
    raise KeyError(key) from err
KeyError: 0

I guess it must be somehow due to df5 = df2[df2['Path'] == path] and df5 = df2[df2['Path']== df2['Path'].iloc[0]] but why?

Is there a possibility to print variables etc. when being in a dash?

I think you should return Device by using iloc. Something as below:

@app.callback(
              Output("Zoomed", "figure"), 
              Input('General', 'clickData')
              )
def update_hover(clickData):
    if clickData:
        path = clickData['points'][0]['hovertext']
        df5 = df2[df2['Path'] == path]
        device_name = df5['Device'].iloc[0]
        return update_zoom_chart(df5, device_name)
    else:
        df5 = df2[df2['Path']== df2['Path'].iloc[0]]
        device_name = df5['Device'].iloc[0]
        return update_zoom_chart(df5, device_name)

1 Like

Hi hoatran,

again, thanks a lot!

When I was trying out inside my prompt to check whether this works it looked good. However, I was even trying
df5['Device'][0].iloc[0]
but yeah, that was obviously not correct.
Can I somehow print out variables when the dash is loaded? In the console it’s not working or…?

Did you try to put print(device_name) to your callback above return?

1 Like

Man, really… If I had I would have bet a million that I tried this a million times… I don’t know what I did wrong but this is working!

Thank you! :slight_smile:

edit: Ah, yeah, I guess the problem arises when there is an error the console is flooded with error lines and I can’t see the print statement anymore. Is there a way to see it?

I did something as below:

@app.callback(
              Output("Zoomed", "figure"), 
              Input('General', 'clickData')
              )
def update_hover(clickData):
    if clickData:
        path = clickData['points'][0]['hovertext']
        df5 = df2[df2['Path'] == path]
        device_name = df5['Device'].iloc[0]
        print(device_name)
        return update_zoom_chart(df5, device_name)
    else:
        df5 = df2[df2['Path']== df2['Path'].iloc[0]]
        device_name = df5['Device'].iloc[0]
        print(device_name)
        return update_zoom_chart(df5, device_name)

Is it your expectations?

This is working when there is no error somewhere.

But I wanna’ use the print statement especially to check the variables when there is something wrong with the code. But then, my console (Spyder) is flooded with hundreds of lines of errors, references to files and lines and so on that I can’t see the print statement anymore.

(...)

  File "pandas\_libs\index.pyx", line 136, in pandas._libs.index.IndexEngine.get_loc
  File "pandas\_libs\index.pyx", line 163, in pandas._libs.index.IndexEngine.get_loc
  File "pandas\_libs\hashtable_class_helper.pxi", line 2131, in pandas._libs.hashtable.Int64HashTable.get_item
  File "pandas\_libs\hashtable_class_helper.pxi", line 2140, in pandas._libs.hashtable.Int64HashTable.get_item
KeyError: 0

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\User\Anaconda3\lib\site-packages\flask\app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\User\Anaconda3\lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\User\Anaconda3\lib\site-packages\flask\app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\User\Anaconda3\lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "C:\Users\User\Anaconda3\lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\User\Anaconda3\lib\site-packages\flask\app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\User\Anaconda3\lib\site-packages\dash\dash.py", line 1273, in dispatch
    ctx.run(
  File "C:\Users\User\Anaconda3\lib\site-packages\dash\_callback.py", line 440, in add_context
    output_value = func(*func_args, **func_kwargs)  # %% callback invoked %%
  File "C:\Users\User\AppData\Local\Temp\ipykernel_21232\1742044449.py", line 263, in update_signal_chart
    print("Device: ", df4['Device'][0])
  File "C:\Users\User\Anaconda3\lib\site-packages\pandas\core\series.py", line 958, in __getitem__
    return self._get_value(key)
  File "C:\Users\User\Anaconda3\lib\site-packages\pandas\core\series.py", line 1069, in _get_value
    loc = self.index.get_loc(label)
  File "C:\Users\User\Anaconda3\lib\site-packages\pandas\core\indexes\base.py", line 3631, in get_loc
    raise KeyError(key) from err
KeyError: 0

and then I can’t even scroll up enough to see the (in case it is even there) print statement.
?

I caused an arbitrary error to show what I see in the IDE console then.

So I think maybe you could use try and except in your callback. Something like below:

@app.callback(
              Output("Zoomed", "figure"), 
              Input('General', 'clickData')
              )
def update_hover(clickData):
    if clickData:
        try:
            path = clickData['points'][0]['hovertext']
            df5 = df2[df2['Path'] == path]
            device_name = df5['Device'].iloc[0]
            print(device_name)
            return update_zoom_chart(df5, device_name)
        except KeyError:
            print(0)
1 Like