Date axis in Makie

I was looking into Makie for plotting some time series but could only find an open issue for having dates on one of the axes. The first suggested fix does not work for me (I get an error when calling lines) and the second seems very verbose. Are there any better options? Maybe with AlgebraOfGraphics?
EDIT:
In addition the second fix leads to weird output in a data example here:

using CairoMakie, CSV, DataFrames, Dates
using PlotUtils: optimize_ticks
readurl(url) = download(url) |> CSV.File |> DataFrame;
datef = dateformat"yyyy-mm-ddTHH:MM:SS+ss:ss";
vaccinations = readurl("https://info.gesundheitsministerium.at/data/timeline-eimpfpass.csv");
vaccinations.date = Date.(vaccinations.Datum, datef);
subset!(vaccinations, :Name => ByRow(==("Ă–sterreich")));
fig = Figure()
ax = Axis(fig[1,1])
dateticks = optimize_ticks(vaccinations.date[1], vaccinations.date[end])[1]
lines!(ax, datetime2rata.(vaccinations.date), vaccinations.EingetrageneImpfungen);
ax.xticks[] =(datetime2rata.(dateticks) , Dates.format.(dateticks, "mm/dd/yyyy"));

Thanks!

1 Like

The problem boils down to this: If you can plot more things into an existing axis, what happens if you plot into a “date axis”. Should you be able to plot only dates? Should it be like a normal axis just with ticks that look like dates? How should the conversion from dates to numbers work? This is all not worked out yet, which is why we don’t have one polished approach. It’s easier for Plots.jl where you assemble a plot top-down once.

1 Like

Gottcha thanks! Unfortunately, I have not idea how that “should” be done. Let me know if I can contribute (e.g. test) something to this topic.

AlgebraOfGraphics would actually be in a better position to deal with this, as its plots are also made in a more top-down style.

1 Like

Currently, I do it manually, like here:
https://lazarusa.github.io/BeautifulMakie/ScattersLines/timeSeries/

2 Likes

Thank you that works great! For completeness here is the example above using @lazarusA’s suggestion

using CairoMakie, CSV, DataFrames, Dates
using PlotUtils: optimize_ticks
readurl(url) = download(url) |> CSV.File |> DataFrame;
datef = dateformat"yyyy-mm-ddTHH:MM:SS+ss:ss";
vaccinations = readurl("https://info.gesundheitsministerium.at/data/timeline-eimpfpass.csv");
vaccinations.date = Date.(vaccinations.Datum, datef);
subset!(vaccinations, :Name => ByRow(==("Ă–sterreich")));
fig = Figure()
ax = Axis(fig[1,1])
days = length(vaccinations.EingetrageneImpfungen)
lines!(ax, 1:days, vaccinations.EingetrageneImpfungen);
ax.xticks = (1:7:days, string.(vaccinations.date)[1:7:days])
ax.xticklabelrotation = π/4
fig

1 Like

I think maybe Axis should have a notion of a unit / be unit-aware. Axes are already associated to numbers (limits and ticks and such) so I think those numbers having a unit would be pretty natural. So if say Axis's had Unitful units, then plotting into an axis with different units would try to convert and if it can’t convert, would fail. And if you want to plot a bunch of stuff with incompatible units on the same axis, just ustrip them first. (This is easier now that Unitful 1.7 interoperates with Dates).

3 Likes

AlgebraOfGraphics supports this already (see time series example). The machinery for this lives in PlotUtils, so this method seems sufficient.

I like @ericphanson’s idea that the tick machinery could interoperate with dates (and other unitful quantities) via Unitful. I think here handling this is not as bad as the categorical conversion we used to have, because there is a well defined transformation from timestamps to floats.

2 Likes

One problem with timestamp to float is our float32 conversion. That would not work for nanoseconds or microseconds I think, maybe even larger units, if the distances between the numbers are too small relative to the absolute values.

Just happened to notice that the manual workaround doesn’t work when we need to zoom in.