Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plotly: How to change the time resolution along the x-axis?

I want to plot some time series data in plotly where the historic portion of the data has a daily resolution and the data for the current day has minute resolution. Is there a way to somehow "split" the x axis so that for the historic data it only shows the date and for the current data it shows time as well?

Currently it looks like this which is not really that readable

enter image description here

like image 351
ACB Avatar asked Oct 24 '25 16:10

ACB


1 Answers

I think the only viable approach would be to put together two subplots. But using the correct setup should make the subplots reach pretty much 100% of what you're describing. You'll only need to adjust a few details like:

fig = make_subplots(rows=1, cols=2,
                    horizontal_spacing = 0,
                    shared_yaxes=True,
                    shared_xaxes=True)

enter image description here

Complete code:

# import pandas as pd
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
from plotly.subplots import make_subplots
import plotly.graph_objects as go

# custom function to set the first
# minute dataset to contiunue from
# the last day in the day dataset
def next_day(date):
    s = date
    date = datetime.strptime(s, "%Y-%m-%d")
    next_date = date + timedelta(days=1)
    return(datetime.strftime(next_date, "%Y-%m-%d"))

# data
np.random.seed(10)
n_days = 5
n_minutes = (2*24)
dfd = pd.DataFrame({'time':[t for t in pd.date_range('2020', freq='D', periods=n_days).format()],
                      'y':np.random.uniform(low=-1, high=1, size=n_days).tolist()})

dfm = pd.DataFrame({'time':[t for t in pd.date_range(next_day(dfd['time'].iloc[-1]), freq='min', periods=n_minutes).format()],
                      'y':np.random.uniform(low=-1, high=1, size=n_minutes).tolist()})
dfm['y'] = dfm['y'].cumsum()

# subplot setup
fig = make_subplots(rows=1, cols=2,
                    horizontal_spacing = 0,
                    shared_yaxes=True,
                    shared_xaxes=True)

# trace for days
fig.add_trace(
    go.Scatter(x=dfd['time'], y=dfd['y'], name = 'days'),
    row=1, col=1
)

# trace for minutes
fig.add_trace(
    go.Scatter(x=dfm['time'], y=dfm['y'], name = 'minutes'),
    row=1, col=2
)

# some x-axis aesthetics
fig.update_layout(xaxis1 = dict(tickangle=0))
fig.update_layout(xaxis2 = dict(tickangle=90))
fig.add_shape( dict(type="line",
                    x0=dfd['time'].iloc[-1],
                    y0=dfd['y'].iloc[-1],
                    x1=dfm['time'].iloc[0],
                    y1=dfm['y'].iloc[0],
                    xanchor = 'middle',
                    xref = 'x1',
                    yref = 'y1',
                    line=dict(dash = 'dash',
                              color="rgba(0,0,255,0.9)",
                              width=1
            )))

fig.update_xaxes(showgrid=False)
fig.update_layout(template = 'plotly_dark')

fig.show()
like image 112
vestland Avatar answered Oct 26 '25 05:10

vestland