From plotly doc:
layout > xaxis > tickvals:
Sets the values at which ticks on this axis appear. Only has an effect if
tickmode
is set to "array". Used withticktext
.layout > xaxis > ticktext:
Sets the text displayed at the ticks position via
tickvals
. Only has an effect iftickmode
is set to "array". Used withtickvals
.
Example:
import pandas as pd
import numpy as np
np.random.seed(42)
feature = pd.DataFrame({'ds': pd.date_range('20200101', periods=100*24, freq='H'),
'y': np.random.randint(0,20, 100*24) ,
'yhat': np.random.randint(0,20, 100*24) ,
'price': np.random.choice([6600, 7000, 5500, 7800], 100*24)})
import plotly.graph_objects as go
import plotly.offline as py
import plotly.express as px
from plotly.offline import init_notebook_mode
init_notebook_mode(connected=True)
y = feature.set_index('ds').resample('D')['y'].sum()
fig = go.Figure()
fig.add_trace(go.Scatter(x=y.index, y=y))
x_dates = y.index.to_series().dt.strftime('%Y-%m-%d').sort_values().unique()
layout = dict(
xaxis=dict(
tickmode="array",
tickvals=np.arange(0, x_dates.shape[0],2).astype(int),
ticktext=x_dates[::2],
tickformat='%Y-%m-%d',
tickangle=45,
)
)
fig.update_layout(layout)
fig.show()
Result:
Since length of x_dates[::2]
is 50 , the ticknumber doesn't match at all .
How do I sovle it ??
Go to 'Axes', then 'Tick Labels' and depending on the axis you want to change, select X, Y, or 'ALL'.
Figures made with Plotly Express can be customized in all the same ways as figures made with graph objects, as well as with PX-specific function arguments.
I normally use the approach below. You should know that tickvals
is to be regarded as a positional argument and works best (perhaps only) with numerical values and not dates. Use ticktext
to display the dates in your preferred format.
Snippet 1:
fig.update_xaxes(tickangle=45,
tickmode = 'array',
tickvals = df_tips['date'][0::40],
ticktext= [d.strftime('%Y-%m-%d') for d in datelist])
Plot 1:
Now you can change tickvals=np.arange(0, y.shape[0]).astype(int)[0::40]
to tickvals=np.arange(0, y.shape[0]).astype(int)[0::80]
and get:
Plot 2:
So why didn't this work for you the first time? A number of reasons:
y.index
were set as x-axis values.y.index
returns dates
fig.update_xaxes(tickvals)
, this works better with integer values.And what did I do to fix it?
y.index
does not return dates..to_frame
.fig.add_trace(go.Scatter(x=y.index, y=y.y))
which otherwise would have failed since this is now a dataframe and not a series.x_dates = y.ds
I know y=y.y
looks really weird, but I just left it like that as a friendly reminder to give your pandas series or dataframes more sensible names than a single letter like y
that's more likely to be confused with a single, index-free, array or list.
Complete code:
import pandas as pd
import numpy as np
import plotly.graph_objects as go
import plotly.offline as py
import plotly.express as px
from plotly.offline import init_notebook_mode
# data
np.random.seed(42)
feature = pd.DataFrame({'ds': pd.date_range('20200101', periods=100*24, freq='H'),
'y': np.random.randint(0,20, 100*24) ,
'yhat': np.random.randint(0,20, 100*24) ,
'price': np.random.choice([6600, 7000, 5500, 7800], 100*24)})
# resampling
y = feature.set_index('ds').resample('D')['y'].sum()#.to_frame()
y=y.to_frame()
y.reset_index(inplace=True)
# plotly setup
fig = go.Figure()
fig.add_trace(go.Scatter(x=y.index, y=y.y))
# x-ticks preparations
x_dates = y.ds
tickvals=np.arange(0, y.shape[0]).astype(int)[0::40]
ticktext=x_dates
# update tickmarks
fig.update_xaxes(tickangle=45,
tickmode = 'array',
tickvals = tickvals,
ticktext=[d.strftime('%Y-%m-%d') for d in ticktext])
fig.show()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With