pythonplotlytimeserieschart

Plotly: How to style a plotly figure so that it doesn't display gaps for missing dates?


I have a plotly graph of the EUR/JPY exchange rate across a few months in 15 minute time intervals, so as a result, there is no data from friday evenings to sunday evenings.

Here is a portion of the data, note the skip in the index (type: DatetimeIndex) over the weekend: enter image description here

Plotting this data in plotly results in a gap over the missing dates Using the dataframe above:

import plotly.graph_objs as go
candlesticks = go.Candlestick(x=data.index, open=data['Open'], high=data['High'],
                   low=data['Low'], close=data['Close'])
fig = go.Figure(layout=cf_layout)
fig.add_trace(trace=candlesticks)
fig.show()

Ouput:

enter image description here

As you can see, there are gaps where the missing dates are. One solution I've found online is to change the index to text using:

data.index = data.index.strftime("%d-%m-%Y %H:%M:%S")

and plotting it again, which admittedly does work, but has it's own problem. The x-axis labels look atrocious:

enter image description here

I would like to produce a graph that plots a graph like in the second plot where there are no gaps, but the x-axis is displayed like as it is on the first graph. Or at least displayed in a much more concise and responsive format, as close to the first graph as possible.

Thank you in advance for any help!


Solution

  • Even if some dates are missing in your dataset, plotly interprets your dates as date values, and shows even missing dates on your timeline. One solution is to grab the first and last dates, build a complete timeline, find out which dates are missing in your original dataset, and include those dates in:

    fig.update_xaxes(rangebreaks=[dict(values=dt_breaks)])
    

    This will turn this figure:

    enter image description here

    Into this:

    enter image description here

    Complete code:

    import plotly.graph_objects as go
    from datetime import datetime
    import pandas as pd
    import numpy as np
    
    # sample data
    df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
    
    # remove some dates to build a similar case as in the question
    df = df.drop(df.index[75:110])
    df = df.drop(df.index[210:250])
    df = df.drop(df.index[460:480])
    
    # build complete timepline from start date to end date
    dt_all = pd.date_range(start=df['Date'].iloc[0],end=df['Date'].iloc[-1])
    
    # retrieve the dates that ARE in the original datset
    dt_obs = [d.strftime("%Y-%m-%d") for d in pd.to_datetime(df['Date'])]
    
    # define dates with missing values
    dt_breaks = [d for d in dt_all.strftime("%Y-%m-%d").tolist() if not d in dt_obs]
    
    # make fiuge
    fig = go.Figure(data=[go.Candlestick(x=df['Date'],
                    open=df['AAPL.Open'], high=df['AAPL.High'],
                    low=df['AAPL.Low'], close=df['AAPL.Close'])
                          ])
    
    # hide dates with no values
    fig.update_xaxes(rangebreaks=[dict(values=dt_breaks)])
    
    fig.update_layout(yaxis_title='AAPL Stock')
    
    fig.show()