plotly / plotly.py

The interactive graphing library for Python :sparkles: This project now includes Plotly Express!
https://plotly.com/python/
MIT License
16.36k stars 2.56k forks source link

holidays on week days behave incorrectly #3134

Open rickpm opened 3 years ago

rickpm commented 3 years ago

Hi Folks,

I am having issues when I have holidays on week days. if I exclude weekends and have a holiday on Friday there is a bug

rangebreaks=[
    # NOTE: Below values are bound (not single values), ie. hide x to y
    dict(bounds=['sat', 'mon']),  # hide weekends, eg. hide sat to before mon
    dict(bounds=[18, 9], pattern='hour'),  # hide hours outside of 9.30am-4pm
    dict(values=["2021-04-02", "2021-12-25"]),  # hide holidays (Christmas and New Year's, etc)
]

(This error originated from the built-in JavaScript code that runs Dash apps. Click to see the full stack trace or open your browser's console.) TypeError: Cannot read property 'val' of undefined

at u (http://127.0.0.1:8050/_dash-component-suites/dash_core_components/async-plotlyjs.v1_15_0m1611086576.js:2:2417931)

at doAutoRange (http://127.0.0.1:8050/_dash-component-suites/dash_core_components/async-plotlyjs.v1_15_0m1611086576.js:2:2420435)

at Object.r.doAutoRangeAndConstraints (http://127.0.0.1:8050/_dash-component-suites/dash_core_components/async-plotlyjs.v1_15_0m1611086576.js:2:2400288)

at S (http://127.0.0.1:8050/_dash-component-suites/dash_core_components/async-plotlyjs.v1_15_0m1611086576.js:2:2374022)

at Object.c.syncOrAsync (http://127.0.0.1:8050/_dash-component-suites/dash_core_components/async-plotlyjs.v1_15_0m1611086576.js:2:2287218)

at http://127.0.0.1:8050/_dash-component-suites/dash_core_components/async-plotlyjs.v1_15_0m1611086576.js:2:2375512

at Object.c.syncOrAsync (http://127.0.0.1:8050/_dash-component-suites/dash_core_components/async-plotlyjs.v1_15_0m1611086576.js:2:2287218)

at Object.r.plot (http://127.0.0.1:8050/_dash-component-suites/dash_core_components/async-plotlyjs.v1_15_0m1611086576.js:2:2376077)

at Object.r.newPlot (http://127.0.0.1:8050/_dash-component-suites/dash_core_components/async-plotlyjs.v1_15_0m1611086576.js:2:2370936)

at Object.r.react (http://127.0.0.1:8050/_dash-component-suites/dash_core_components/async-plotlyjs.v1_15_0m1611086576.js:2:2380532)
gtarabat commented 2 years ago

I believe the problem I have is related to the above. Running the following code produces an empty figure.

import pandas as pd
import numpy as np
import plotly.graph_objects as go

date_range1 = pd.date_range(start='1/1/2020 10:00:00 ', end='1/1/2020 16:00:00', freq='h')
date_range2 = pd.date_range(start='1/7/2020 10:00:00 ', end='1/7/2020 16:00:00', freq='h')
date_range = date_range1.union(date_range2)

df = pd.DataFrame(index=date_range)
df['y'] = np.linspace(1, len(df.index.values), len(df.index.values))

fig = go.Figure()
fig.add_trace(go.Scatter(x=df.index, y=df['y']))
fig.update_xaxes(
    rangebreaks=[
        dict(bounds=[16, 10], pattern="hour"),
        dict(bounds=["sat", "mon"]),
        dict(values=["2020-01-02", "2020-01-03", "2020-01-04", "2020-01-05", "2020-01-06",]),
    ]
)
fig.show()

If I remove

dict(bounds=[16, 10], pattern="hour"),
dict(bounds=["sat", "mon"]),

or

dict(values=["2020-01-02", "2020-01-03", "2020-01-04", "2020-01-05", "2020-01-06",]),

the expected figure is produced.

A-Wpro commented 2 years ago

I got the same problem with a similar code, I can confirm @gtarabat analysis, if you use bounds with rangebreak a big part of the graph, eventually all the graph is missing. It seems to be a bug that already occurred in 2020 and still exists today.

A-Wpro commented 2 years ago

If someone is still looking for a way to make a rangebreak without using bounds you can use this :

rangebreaks=[dict(pattern="hour",dvalue = 6*24*60*60*1000-7*60*60*1000, values=["2020-01-01 17:00:00"])]

values are the start of every break you want. Here we want only 1 break starting at "2020-01-01 17:00:00" dvalue is the duration of each break. Here we have a break of 6 days - 7 hours. (6d 24h 60m 60sec 1000ms - 7h 60m 60sec * 1000ms)

Of course, there is still a problem to fix.