Center date period as tick label between tick marks for time series plots

Time series labels are usually not the easiest to read, because plotting software treats dates as instant in time.
Is there a way to label time series ticks to show the time period rather than a point in time?

Take the following example;

The x tick labels are centred on the start of the month. When I go to look at a time series I want to know what time period it happened in, not what the start date of that period was. Surely everyone would rather see this x tick labelling;

You could apply this to a larger period of time (say calendar quarters). So instead of doing this;

You would do this;

Again, surely this is easier to read at a glance what time period something happened in rather than what the precise start date of that time period was?

You could take that logic and apply it to years in a decade, or days in a month (or hours in a day) and so on.

I canโ€™t be the only one that finds the standard way of plotting time series non-intuitive and would rather see it the alternative way?

How could I go about implementing a change so all users could use this option?

hi @shoops
How about something like this example?

Hi @shoops,
I may have found what you need here.
The year is not centered, it is displayed below the first label, but that is a good formatting too.

You can add ticks also:

fig.update_xaxes(
    dtick="M1",
    tickformat="%b\n%Y",
    ticklabelmode="period",

    ticks="inside",
    minor=dict(
        ticks="outside",
        tickwidth=2,
        ticklen=30,
        dtick="M12",

    ),
)

And easily change the periods:

fig.update_xaxes(

    dtick="M3",
    tickformat="Q%q\n%Y",

    ticklabelmode="period",
    ticks="inside",
    minor=dict(
        ticks="outside",
        tickwidth=2,
        ticklen=30,
        dtick="M12",
    ),
)

5 Likes

Awesome, thanks @Skiks, that ticklabelmode="period" option was exactly what I was looking for. I didnโ€™t know it existed!

I see the year part of tickformat is where the year label comes from, and it is only for the first ticklabel. I wonder why this is the case?

Also, I wonder why you canโ€™t add an actual label for the minor ticks?

Any idea if ticklabelmode="period" works with tickformatstops?

1 Like

Thanks for the reply @adamschroeder. Iโ€™ll keep Enumerated ticks in mind.

Hi @shoops,
Glad to help as brand-new member of the forum! :tada:

Itโ€™s a kind of trick, like described in the previous example:

Date axis tick labels have the special property that any portion after the first instance of โ€˜\nโ€™ in tickformat will appear on a second line only once per unique value, as with the year numbers in the example below. To have the year number appear on every tick label, '<br>' should be used instead of โ€˜\nโ€™.


Indeed I didnโ€™t find a way to display labels on minor ticks :thinking:


I ran some tests using this example, it seems that they donโ€™t play well together

Vanilla

With ticklabelmode="period"
It seems the labels shift a little, but not in the center of the periods

With ticklabelmode="period" and dtick="M1"
The labels come back on ticks

Zooming to have horizontal labels

Anyway, it seems it is not possible to define custom tick periods depending on the zoom level.
tickformatstops only allows to define only labels format depending on the zoom level

Maybe the solution can be to create a kind of custom tickformatstops using Dash and Graph prop relayoutData as input of a callback, which is triggered with zoom/pan. See exemple here

2 Likes