How to enable automatic autoscale

I’m still struggling to get this to work. I’ve played with both Graph.animate and Layout.autorange and nothing seems to work.

My code works as follows. I have market data preloaded into a MongoDb database. I created a “Next data” button to allow me to iterate through each document/row of the database, so that I can walk forward bar-by-bar. The Graph should display the last 100 bars of the market data (I’m using collections.deque to do that). So clicking the “Next data” button should display the latest bar of data, and drop off the oldest.

When I first click “Next data” it works fine, but after clicking several more times I’m noticing that I’m getting old data bars still displayed (almost like its walking backwards). Eventually no bars show up since the Y-Axis is all messed. But I observed that clicking “Autoscale” in the upper right hand corner fixes it each time. So to get this to work I’m forced to click on “Autoscale” after each “Next data” click.

Any thoughts on how to solve?

Here’s my code:

# System imports
from collections import deque
import random
import time

# Flash imports
from flask import Flask

# MongoDb imports
from pymongo import MongoClient

# Plotly imports
import plotly.graph_objs as go
import plotly

# Dash imports
import dash
from dash.dependencies import Input, Output, Event
import dash_core_components as dcc
import dash_html_components as html


MaxBars = 100
Dts = deque(maxlen=MaxBars)
Open = deque(maxlen=MaxBars)
High = deque(maxlen=MaxBars)
Low = deque(maxlen=MaxBars)
Close = deque(maxlen=MaxBars)

server = Flask(__name__)

MONGODB = "mongodb"
MONGODB_PORT = 27017
Symbol = 'ES'

Client = MongoClient(MONGODB, MONGODB_PORT)
Collection = getattr(Client.historical, Symbol)
#Cursor = Collection.find()
dateFromString = {
   "$dateFromString": {
      "dateString": {
         "$concat": ["$Date", "$Time"]
      }
   }
}
project = {
   'dts': dateFromString,
   'Open': 1,
   'High': 1,
   'Low': 1,
   'Close': 1,
   'Volume': 1,
}

pipeline = [
   {"$project": project},
   {"$sort": {"dts": 1}},
]

startTime = time.time()
print("Loading data from MongoDb")
Cursor = Collection.aggregate(pipeline, allowDiskUse=True)
for _ in range(MaxBars):
   Bar = Cursor.next()
   Dts.append(Bar['dts'])
   Open.append(Bar['Open'])
   High.append(Bar['High'])
   Low.append(Bar['Low'])
   Close.append(Bar['Close'])
   print("{}".format(Bar))
print("Finished loading data from MongoDb (duration={:2.2f}s)".format(
      time.time() - startTime
))

app = dash.Dash(server=server)
app.layout = html.Div(
   [
      dcc.Graph(id='live-graph', animate=False),
      #dcc.Interval(id='graph-update', interval=1*1000),
      html.Button('Next data', id='button'),
   ]
)

@app.callback(
   output=Output('live-graph', 'figure'),
   inputs=[
      Input('button', 'n_clicks'),
   ]
   #state=
   #events=[
   #   #Event('graph-update', 'interval'),
   #]
)
def update_graph(n_clicks):
   print("Update graph")

   Bar = Cursor.next()
   Dts.append(Bar['dts'])
   Open.append(Bar['Open'])
   High.append(Bar['High'])
   Low.append(Bar['Low'])
   Close.append(Bar['Close'])
   print("{}".format(Bar))

   data = go.Candlestick(x=list(Dts),
                         open=list(Open),
                         high=list(High),
                         low=list(Low),
                         close=list(Close))

   layout = go.Layout(
      title="{}".format(Symbol),
      xaxis=dict(
      #   range=[min(Dts),max(Dts)],
         rangeslider=dict(visible=False)
      ),
      yaxis={
         #'title': 'Price ($)',
         'autorange': True,
      #   #range=[0,max(High)+100],
      },
   )

   return {
      'data': [data],
      'layout': layout,
   }


if __name__ == '__main__':
   print("Starting chart app")
   App.run_server(debug=True)