Reputation: 1057
I am having last 1 year time series financial data. I removed weekends as no data is present.
I created plotly viz, 2w
,1m
range selector buttons are not showing correct time range.
While YTD
,6m
,all
showing correct data.
2w
button showing 2 week forward days but there is no data, i want to see last two week and 1m data.
Reproducable Code-
# !pip install investpy
import pandas as pd
import investpy
import datetime
import plotly.graph_objects as go
import plotly.figure_factory as ff
import plotly.express as px
today = datetime.now() #Today Datetime
today_fut = today.strftime("%Y,%m,%d") #Converting today date to string format "%Y,%m,%d"
today_fut = datetime. strptime(today_fut, '%Y,%m,%d').date() #Converting today's date to "date" format for NSE Tools library
today = today.strftime("%d/%m/%Y") #Converting today date to string format "%d/%m/%Y"
one_year= datetime.today() - timedelta(days=370) #Subrtracting todays date with 370 Days
one_year = one_year.strftime("%d/%m/%Y") #Converting into string format "%d/%m/%Y"
df = investpy.get_index_historical_data(index="Nifty 50",country="India",from_date=str(one_year),to_date= str(today))
print("Investpy NF Dataframe",df.tail())
bnf = investpy.get_index_historical_data(index="Nifty Bank",country="India",from_date=str(one_year),to_date= str(today))
print("Investpy BNF Dataframe",bnf.tail())
fig = go.Figure(data = [ go.Scatter(x = df.index,y = df['Close'],line=dict(color = 'Steelblue',width=2),mode='lines+markers',name = 'NIFTY'),
go.Scatter(x = bnf.index,y = bnf['Close'],line=dict(color = 'yellowgreen',width=2),mode='lines+markers',name = 'BANK NIFTY'),
])
fig.update_layout(
title='NF and BNF',template = 'plotly_dark',xaxis_tickformat = ' %d %B (%a)<br> %Y',
yaxis_title='NF & BNF',yaxis_tickformat= "000",yaxis_side = 'right',xaxis_title='Date',legend = dict(bgcolor = 'rgba(0,0,0,0)'))
layout = go.Layout(showlegend=True)
##https://plotly.com/python/legend/
fig.update_layout(legend=dict(
yanchor="top",
y=0.99,
xanchor="left",
x=0.01 ))
#hide weekends
fig.update_xaxes( rangeslider_visible=True, rangebreaks=[
dict(bounds=["sat", "mon"]) ])
##https://plotly.com/python/legend/
fig.update_layout(legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1
))
config = dict({'scrollZoom': False})
fig.update_layout(
xaxis=dict(rangeselector=dict(buttons=list([
dict(count=14,label="2w",step="day",stepmode="todate"),
dict(count=1,label="1m",step="month",stepmode="backward"),
dict(count=3,label="3m",step="month",stepmode="backward"),
dict(count=6,label="6m",step="month",stepmode="backward"),
dict(count=1,label="YTD",step="year",stepmode="todate"),
dict(step="all") ])),rangeslider=dict(visible=True),type="date"))
fig.update_layout(
xaxis_rangeselector_font_color='white',
xaxis_rangeselector_activecolor='red',
xaxis_rangeselector_bgcolor='green',
)
fig.show()
pio.write_html(fig, file='wrong_range_selecor_for-2w&1m_button.html', auto_open=True)
Pls let me know , if there is any bug in plotly range selector or I am doing something wrong in xaxis=dict(rangeselector=dict(buttons=list([xaxis=dict(rangeselector=dict(buttons=list([
code.
Snap- When I click on 2w
but it show future dates, where no data is present in dataframe.
Upvotes: 1
Views: 1281
Reputation: 16045
Yes it seems like a bug with the range selector (type='date'
). It occurs when setting the scatter plot mode to 'markers'
or 'lines+markers'
: in fact, using markers leads to the addition of an extra range added to the xaxis, extending the default date range from the input data.
So when you click on 2w
, the slider goes from that out-of-range date (in the future) back to 2w before that date, the same happens with the other ranges actually, not only 1m
, but it is less noticeable for bigger ones.
You could set a fixed range to circumvent the problem using rangeslider_range
and range
:
fig.update_xaxes(
rangeslider_visible=True,
rangebreaks=[dict(bounds=["sat", "mon"])],
range=[df.index[0], df.index[-1]],
rangeslider_range=[df.index[0], df.index[-1]]
)
...until you click on "all". The problem is that the range selector button step='all'
will always reset the layout to use the extended range.
This does not happen when you set the scatter mode to just mode='lines'
. In this case the default/'all' slider range fits the data.
So I guess the quick fix is to remove markers, the long one is to use Dash callbacks to have a full control of what the buttons do.
Upvotes: 2