Reputation: 61204
I'm trying to display a horizontal bar chart with dates on the x-axis, but can't seem a way to do that although the x-values are dates of type string. As you can see below, the numbers that occur as ticklabels have to be a summation of some sort, but I'm not sure exactly what. How can you change the example below to get dates as ticklabels?
Plot 1:
Code:
# imports
import numpy as np
import pandas as pd
import plotly.express as px
from datetime import datetime
# data
np.random.seed(1)
cols=list('ABCDE')
df = pd.DataFrame(np.random.randint(0,2,size=(5, len(cols))), columns=cols)
drng=pd.date_range(datetime(2020, 1, 1).strftime('%Y-%m-%d'), periods=df.shape[0]).tolist()
df['date']=[d.strftime('%Y-%m-%d') for d in drng]
dfm=pd.melt(df, id_vars=['date'], value_vars=df.columns[:-1])
# plotly express
fig = px.bar(dfm, x="date", y="variable", color='value', orientation='h',
hover_data=["date"],
height=400,
color_continuous_scale=['blue', 'teal'],
title='Custom date ticklabels for vertical bar plot',
template='plotly_white',
)
fig.update_traces(showlegend=False)
fig.update(layout_coloraxis_showscale=False)
fig.show()
What I've tried:
I've tried different combinations for tickmode
, tickvals
and ticktext
for xaxis=dict()
in fig.update_layout
, alas with completely useless results.
Attempt 2: ticktext
Set tickvals=df['date']
fig.update_layout(yaxis=dict(title=''),
xaxis=dict(title='',
gridcolor='grey',
#tickmode= 'array',
#tickmode= 'linear',
#tick0= 2220,
#dtick=200,
#tickvals= [2020, 2040],
ticktext = df['date'])
)
Plot 2:
Same as before:
Attempt 3: ticktext
& dtick
To my amazement, setting dtick
to some arbitrary value gives you the plot below.
fig.update_layout(yaxis=dict(title=''),
xaxis=dict(title='',
gridcolor='grey',
#tickmode= 'array',
#tickmode= 'linear',
tick0= 2050,
dtick=2,
#tickvals= [2020, 2040],
ticktext = df['date'])
)
Plot 3:
Still amazingly useless, but now the ticks at least looks like dates, although we're looking at a value that represents a timestamp in 2008
and the source data is 2020
...
Attempt 4: tickvals
and ticktext
fig.update_layout(yaxis=dict(title=''),
xaxis=dict(title='',
gridcolor='grey',
#tickmode= 'array',
#tickmode= 'linear',
tick0= 2050,
#dtick=2,
tickvals= [2050, 2100, 2150, 2200],
ticktext = df['date'])
)
Plot 4:
From the looks of if, this is exactly what I'm looking for:
But this is equally useless like the other attempts, since we have to specify tickvals= [2050, 2100, 2150, 2200]
. If we change the period, these values will have to be re-specified, and that's not very flexible. Of course, if we somehow could retrieve the default tickvalues used by plotly, we could easily replace them with the dates in the dataset. But that seems to still be impossible according to the answer to the post Plotly: How to retrieve values for major ticks and gridlines?
I'm at a complete loss here, and baffled by the uselessness of my attempts, so any other suggestions would be great!
Upvotes: 3
Views: 17028
Reputation: 11
You have to set programmatically both the ticks values and labels. Suppose to have a dataset having Date and Timestamp and that you want only 10 ticks in the x axis to be shown, then:
tickvals=[df["Timestamp"][j] for j in range(0,len(df["Timestamp"]),int(len(df["Timestamp"])/10))]
ticktext=[df["Date"][j] for j in range(0,len(df["Date"]),int(len(df["Date"])/10))]
fig.update_layout(
xaxis = dict(
tickmode = 'array',
tickvals = tickvals,
ticktext = ticktext,
)
)
Note: remember to sort dates before generating timestamps!
Upvotes: 0
Reputation: 41
You must activate tickmode
to 'array' and then define tickvals
and ticktext
, like:
tickmode = 'array',
tickvals = [2050, 2100, 2150, 2200],
ticktext = df['date'])
Upvotes: 4