Limit data in graphics

Is there any way to limit the data that is shown in the graph ?, It show me data from 3 days ago and I would like it to only show a certain amount, the most current, because if not then the graph is very saturated.

This is my code:

app = dash.Dash(
__name__,
server = server,
routes_pathname_prefix='/dashHUM/'
)

app.layout = html.Div("My Dash app")

app.layout = html.Div(children=[
    
html.H1(children='Sensores Libelium ',
        style={
        'textAlign': 'center',
        'color': colors['text']
    }, className='banner'),
html.H3(children='Dash: Humedad', style={
    'textAlign': 'center',
    'color': colors['text']
}),
html.Div([
    html.Div([
        html.H2("%", style={
    'color': colors['text']
})
    ], className='Title'),
    html.Div([
        dcc.Graph(id='example-graph1'),
    ], className='twelve columns wind-speed'),
    dcc.Interval(id='graph-update1', interval=1000, n_intervals=0),
], style={'padding': '0px 10px 15px 10px'},className='row wind-speed-row'),
], style={'padding': '0px 10px 15px 10px',
      'marginLeft': 'auto', 'marginRight': 'auto', "width": "1100px",
      'boxShadow': '0px 0px 12px 5px rgba(204,204,204,0.4)',
      'background': 'rgba(247,247,247,0.6)'})

@app.callback(Output('example-graph1', 'figure'),
              [Input('graph-update1', 'n_intervals')])


def update_graph1(interval):

    now = dt.datetime.now()
    sec = now.second
    minute = now.minute
    hour = now.hour

    total_time = (hour * 3600) + (minute * 60) + (sec)

    dataSQL = []
    X = deque(maxlen=10)    
    Y = deque(maxlen=10)

    sql_conn = MySQLdb.connect('localhost', 'root', 'password', 'DB')
    cursor = sql_conn.cursor()
    cursor.execute("SELECT value,timestamp FROM sensorParser where sensor='HUM'")
    rows = cursor.fetchall()
    for row in rows:
        dataSQL.append(list(row))
        labels = ['value','timestamp']
        df = pd.DataFrame.from_records(dataSQL, columns=labels)
        X = df['timestamp']
        Y = df['value']
    

    data = plotly.graph_objs.Scatter(
            x=list(X),
            y=list(Y),
            name='HUM',
            mode= 'lines+markers'
            )

    return {'data': [data],'layout' : go.Layout(title="HUMEDAD",xaxis=dict(range=[min(X),max(X)]),
                                                yaxis=dict(range=[min(Y),max(Y)]),)}

Regards.

You could use the extendData property which includes maxPoints in its API. maxPoints limits the number of points that are saved. Using extendData also allows you to reduce the amount of data being passed back and forth in each query. A sketched out example below:

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

MAX_POINTS_TO_SHOW = 15
TRACE_TO_UPDATE = 0

app = dash.Dash()
app.scripts.config.serve_locally = True
app.css.config.serve_locally = True

app.layout = html.Div([
    html.Div([
        dcc.Graph(
            id='graph-extendable',
            figure={'layout': {'title': 'Random title',
                               'barmode': 'overlay'},
                    'data': [{'x': [], 'y': []}, {'x': [], 'y': []}] # initialize 2 traces, indexes 0 and 1
                    },
        ),
        dcc.Store(
            id='storage-graph-extendable',
        )
    ]),

    dcc.Interval(
        id='interval-graph-update',
        interval=500,
        n_intervals=0),
])

def getSensorDataSinceTimestamp(t):
    """collect any new data since the last query"""
    ...
    cursor.execute("SELECT value,timestamp FROM sensorParser where sensor='HUM' AND timestamp > {}".format(t))
    ...    
    return x, y
    
@app.callback([Output('graph-extendable', 'extendData'),
               Output('storage-graph-extendable', 'data')],
              [Input('interval-graph-update', 'n_intervals')],
              [State('storage-graph-extendable', 'modified_timestamp')]
              )
def extend_single_trace(n_intervals, last_updated):
    """
    Collect any new data that has occurred in the last 500ms, based on the last time that this method was executed.
    
    Instead, you could use the most recent data point that exists on the figure:
        in callback: add [State('graph-extendable', 'figure')]
        in method: check figure['data'][0]['x'][-1]
    """
    last_updated_timestamp = pd.to_datetime(last_updated, unit='ms') # convert from posix msec to a pandas Timestamp
    x, y = getSensorDataSinceTimestamp(last_updated_timestamp)

    """
    If there is no new data, don't update the trace.
    """
    if x is None:
        raise PreventUpdate 
        
    """
    multiple outputs:
    1. extend data for TRACE_TO_UPDATE and limit total data length to MAX_POINTS_TO_SHOW
    2. update storage-graph-extendable so that modified_timestamp changes (next time this method is executed)
    """

    # transform data to match the Plotly.extendTraces API
    new_values = dict(x=[[x]], y=[[y]])
    return (
        (new_values, [TRACE_TO_UPDATE], MAX_POINTS_TO_SHOW),
        n_intervals
    )


app.run_server(debug=True)
1 Like