"Resetting" Figure Data with Module Call and Maintaining Data

Sorry if this question is incoherent or easily solvable; I’m very new to Dash and Flask.

I’m currently writing an application that grabs data from objects using a python module. Using this data, it calculates an object’s path and displays multiple of these objects on a graph as points where a slider can be used to show movement over time as an animation.

The initial data retrieval is by choosing a center object and grabbing near by objects around it.

The issue I’m running into is I’d like to allow a user to be able to specify which object to center the graph on through an input. This would require another call to the module, because it is not possible (nor efficient) to store all possible data inputs in the application. My issue is then maintaining this data so that the slider can continue to be used.

I’ve considered:

  • HTTP protocols (get/post): Do not seem to be supported by Dash
  • Storing data in browser: Seemed nonviable because it seemed impossible to then clear a set of data when a new center was chosen
  • Multiple inputs per callback (reading input to for center and input for time): Seemed problematic because re-initializing data is very expensive, and having to do this every time the slider is moved is unideal
  • Modifying global variables: Should be avoided in Dash

Sorry for the vagueness of this question, but I’m a little lost at what tools I could use to solve this issue.

Hi @Ischium welcome to the forums.

At first glace, it should be possible to do in Dash what you are describing.

What are you referring to?

You can use (different) dcc.Store() for that.

I don’t fully understand that, but you can trigger the data update by a button click, for example.

Hey, thanks for your help.

HTTP protocols: My idea was to let users input a centering object’s name (or additional parameters) and submit this, calling a post method that would retrieve data from the module and rebuild the graph from scratch any time new parameters are used. That way, only one data set is used on the page without reload. I couldn’t find though anything on using these, though. I may have missed documentation though.

I tried to store data with dcc.Store(), what I attempted to do was store a data set once processed but struggled with “syncing” these changes to the time slider. Process wise, something like this (using pseudo code-ish for brevity):

app.layout = html.Div([
   html.Div(dcc.input(id = 'center-input', value = 'initial', type = 'text')),
   html.Button('Submit', id = 'submit-button', n_clicks = 0),
   html.Div([
      dcc.Graph(id = 'graph', figure = alreadyMadeFigure)
      dcc.Slider(id = 'time-slider', ...)
   ])
])
@callback(
   Output('graph', 'figure',  allow_duplicate = True),
   Input('time-slider', 'value'),
   prevent_initial_call = True
)
def renderGraph(day):
   # reprocess data to recalculate positions
   patch = patch()
   patch['data'][0]['x'] = newX
   patch['data'][0]['y'] = newY
   return patch
@callback(
   Output('graph', 'figure'),
   Input('submit-button', 'n_clicks'),
   State('center-input', 'value')
)
def updateCenter(nClicks, value):
   newDataSet = module(value)
   for point in newDataSet:
      object = json.dumps(point.__dict__)
      jsonObject += object
   dcc.Store(id = 'json-data', data = jsonObject)
   # recreate graph = figure
   return  figure

It is possible I am fundamentally misunderstanding dcc.Store() though and would need to use a new method of doing this.

Multiple inputs per callback: I misphrased; I meant if I were to rebuild the data set every time the time slider is used–which seemed like a possible solution would be to take the center input and the time slider into one callback–it would be very expensive.

Thanks again for the help, and sorry if any of this is incoherent.