0

I am trying to format my x-axis ticks to show only "Mondays" on a series of graphs. The example below is an MRE but it is not what I am directly working on, but it is close enough (plotly example from https://plotly.com/python/heatmaps/). Now I know these graphs can be zoomed in and out, but I am wondering if when it shows a range of about 4 months or 120 days on the graph, how can I configure this graph to show Mondays by default, rather than Sundays?

I almost had it by setting "tick0='2022-07-04'" which is a Monday and setting "dtick=604800000" which did give me the desired output, but upon zoomning in it did not show days, hours, minutes, or seconds which is a feature I am still desiring. Does anyone have a solution for this?

import plotly.graph_objects as go
import datetime
import numpy as np
np.random.seed(1)

programmers = ['Alex','Nicole','Sara','Etienne','Chelsea','Jody','Marianne']

base = datetime.datetime.today()
dates = base - np.arange(120) * datetime.timedelta(days=1)
z = np.random.poisson(size=(len(programmers), len(dates)))

fig = go.Figure(data=go.Heatmap(
        z=z,
        x=dates,
        y=programmers,
        colorscale='Viridis'))

fig.update_layout(
    title='GitHub commits per day',
    xaxis_nticks=36)

fig.update_xaxes(showgrid=True, gridwidth=2, gridcolor='white', type='date',
    rangeslider_visible=False, ticks='outside', tickson='boundaries', ticklen=20,
    tickformatstops = [
        dict(dtickrange=[None, 1000], value="%H:%M:%S.%L\n%b %e %Y"), # Hours, minutes, seconds, milliseconds \n month, year
        dict(dtickrange=[1000, 60000], value="%H:%M:%S\n%b %e %Y"), # Hours, minutes, seconds \n month, day, year
        dict(dtickrange=[60000, 3600000], value="%H:%M\n%b %e %Y"), # Hours, minutes \n month, day, year
        dict(dtickrange=[3600000, 86400000], value="%b %e (%a)\n%Y"), # Hours, minutes \n month, day, year
        dict(dtickrange=[86400000, 604800000], value="%b %e (%a)\n%Y"), # Month, day, (day of week), year (SHOW MONDAY HERE, INSTEAD OF SUNDAY)
        dict(dtickrange=[604800000, "M1"], value="%b %e (%a)\n%Y"), # Month, day, (day of week), year (SHOW MONDAY HERE, INSTEAD OF SUNDAY)
        dict(dtickrange=["M1", "M12"], value="%B\n%Y"), # Month, year
        dict(dtickrange=["M12", None], value="%Y")] # Year   
    )

fig.show()

Plotly Example - Modified

IDK
  • 99
  • 2
  • 9

1 Answers1

0

If you add a date start value, a date interval, and a further date format, the date, month, and day of the week will be displayed even when zoomed in.

import plotly.graph_objects as go
import datetime
import numpy as np
np.random.seed(1)

programmers = ['Alex','Nicole','Sara','Etienne','Chelsea','Jody','Marianne']

base = datetime.datetime.today()
dates = base - np.arange(120) * datetime.timedelta(days=1)
dates = pd.to_datetime(dates)
z = np.random.poisson(size=(len(programmers), len(dates)))

fig = go.Figure(data=go.Heatmap(
        z=z,
        x=dates,
        y=programmers,
        colorscale='Viridis'))

fig.update_layout(
    title='GitHub commits per day',
    xaxis_nticks=36)

#fig.update_xaxes(type='date', tick0='2022-07-04', dtick=604800000, tickformat='%d %b (%a)')


fig.update_xaxes(showgrid=True,
                 gridwidth=2, 
                 gridcolor='white',
                 type='date',
                 rangeslider_visible=False,
                 ticks='outside', 
                 tickson='boundaries',
                 ticklen=20,
                 tickformatstops = [
                     dict(dtickrange=[None, 1000], value="%H:%M:%S.%L\n%b %e %Y"),
                     dict(dtickrange=[1000, 60000], value="%H:%M:%S\n%b %e %Y"),
                     dict(dtickrange=[60000, 3600000], value="%H:%M\n%b %e %Y"),
                     dict(dtickrange=[3600000, 86400000], value="%b %e (%a)\n%Y"),
                     dict(dtickrange=[86400000, 604800000], value="%b %e (%a)\n%Y"),
                     dict(dtickrange=[604800000, "M1"], value="%b %e (%a)\n%Y"),
                     dict(dtickrange=["M1", "M12"], value="%B\n%Y"),
                     dict(dtickrange=["M12", None], value="%Y")]        
    )

fig.show()

enter image description here

r-beginners
  • 31,170
  • 3
  • 14
  • 32
  • Thank you for your answer. I had gotten that far but I am also seeking upon zooming in for the days to be named individually when the zoom level gets to that close of a micro scale. and Upon further zooming in, hours, minutes, and seconds to also appear when appropriate. Essentially I want to mimic to the default zoom behavior and the only thing I want to change is to have it call out 'Mondays' instead of 'Sundays' at the zoom level in my previously attached picture. – IDK Oct 26 '22 at 15:11
  • I am not sure what state and display you are ultimately seeking. What do you want to display in the micro state? I need specific examples. Handwritten is fine, can you share? – r-beginners Oct 27 '22 at 00:43
  • I edited my original code above, as it was too much to fit into a comment. Please see this section of my code in my original post. fig.update_xaxes(showgrid=True, gridwidth=2, gridcolor='white', type='date', rangeslider_visible=False, ticks='outside', tickson='boundaries', ticklen=20, tickformatstops = [ dict(dtickrange=[None, 1000], value="%H:%M:%S.%L\n%b %e %Y"), .... .... dict(dtickrange=["M12", None], value="%Y") – IDK Oct 27 '22 at 14:30
  • I found the cause. It was due to the fact that the time series data was not Datetimeindex. Updated the code and graphs. I tried your time series setup with [this sample](https://plotly.com/python/time-series/#customizing-tick-label-formatting-by-zoom-level) in the reference and it displays correctly. – r-beginners Oct 27 '22 at 14:38