Thanks @Emmanuelle! I considered this but tickformatstops won’t cut it for me, since completely different axes are needed. The code and chart below show more or less what I have mind.
cheers,
Maarten
import datetime as dt, numpy as np, plotly.graph_objs as go
from scipy.stats import norm
from calendar import monthrange
nCategory = 5
nDays = 100
# generate bar data
base = dt.datetime.combine(dt.date.today(),dt.time(hour=12,minute=0))
date_list = [base + dt.timedelta(days=x) for x in range(nDays)]
barData = []
categoryLabels = []
barChart = []
for i in range(nCategory):
barData = norm.rvs(4,1,nDays).tolist()
barChart.append(go.Bar(x=date_list,y=barData, xaxis = 'x1',name = str(i), hovertemplate = '<b>%{x|%x}<br>%{y}<br></b>'))
xaxis1_vals = date_list
xaxis1_text = ['' for d in date_list]
xaxis1 = go.layout.XAxis(tickvals = xaxis1_vals,ticktext = xaxis1_text, showgrid = False)
# x-axis for the week numbers
dummyScatter1 = go.Scatter(x=date_list,y=[-1]*nDays, xaxis = 'x2',showlegend = False,hoverinfo='skip')
xaxis2_vals = [d for d in date_list if d.isoweekday()==3]
xaxis2 = go.layout.XAxis(matches = "x1",anchor="x1",overlaying="x1",
tickcolor = 'rgba(0,0,0,0)', tickformat = '%U',
tickvals = xaxis2_vals, showgrid = False)
# x-axis for the dividers between weeks
dummyScatter2 = go.Scatter(x=date_list,y=[-1]*nDays, xaxis = 'x3',showlegend = False,hoverinfo='skip')
xaxis3_vals = [d.date() for d in date_list if d.isoweekday()==7]
xaxis3_text = ['']*len(xaxis3_vals)
xaxis3 = go.layout.XAxis(matches = "x1",anchor="x1",overlaying="x1",ticklen = 10,
ticks= 'outside',tickvals = xaxis3_vals, ticktext = xaxis3_text, showgrid = False, gridwidth=5)
# x-axis for the month names
dummyScatter3 = go.Scatter(x=date_list,y=[-1]*nDays, xaxis = 'x4',showlegend = False,hoverinfo='skip')
xaxis4_vals = []
for d in date_list:
if d.day == np.floor(monthrange(d.year,d.month)[1]/2):
xaxis4_vals.append(d + dt.timedelta(days=np.mod(monthrange(d.year,d.month)[1],2)/2))
xaxis4 = go.layout.XAxis(matches = "x1",anchor="x1",overlaying="x1",
tickcolor = 'rgba(0,0,0,0)', tickformat = '%B',
tickvals = xaxis4_vals, ticks= 'outside', ticklen = 30, showgrid = False)
# x-axis for the dividers between months
dummyScatter4 = go.Scatter(x=date_list,y=[-1]*nDays, xaxis = 'x5',showlegend = False,hoverinfo='skip')
xaxis5_vals = [d.date() for d in date_list if d.day==monthrange(d.year,d.month)[1]]
xaxis5_text = ['']*len(xaxis5_vals)
xaxis5 = go.layout.XAxis(matches = "x1",anchor="x1",overlaying="x1",ticklen = 50,
ticks= 'outside', tickvals = xaxis5_vals, ticktext = xaxis5_text, showgrid = True)
yaxis = go.layout.YAxis(rangemode = 'nonnegative')
layout = go.Layout(xaxis=dict(), barmode = 'stack', xaxis1 = xaxis1, xaxis2 = xaxis2,
xaxis3 = xaxis3, xaxis4 = xaxis4, xaxis5 = xaxis5, yaxis = yaxis, hovermode = 'x')
fig = go.Figure(data=barChart + [dummyScatter1,dummyScatter2,dummyScatter3,dummyScatter4],layout=layout)
fig.show()