Range Breaks on DateTimeAxis in Makie

Hi I want to plot the following data. I have the last 3 closing prices from one day and the first 3 closing prices from the next day.

6×2 DataFrame
 Row │ timestamp            close   
     │ DateTime             Float64
─────┼──────────────────────────────
   1 │ 2024-08-26T15:00:00  560.84
   2 │ 2024-08-26T15:30:00  560.45
   3 │ 2024-08-26T16:00:00  560.73
   4 │ 2024-08-27T10:00:00  559.825
   5 │ 2024-08-27T10:30:00  561.075
   6 │ 2024-08-27T11:00:00  561.63

A scatter plot produces the figure shown below

f = Figure()
ax, scatter_plot = scatter(f[1, 1], df[!, :timestamp], df[!, :close])
f

My problem is there is a massing gap between the hours 16:00 and 09:30 the next day. What would be a good approach to correct for this in Makie?

Something similar to this PlotlyJS feature would be ideal but I don’t think Makie has the concept of range breaks built in, does it?

I was thinking as a hack maybe map the dates to Ints and then override the tick lables, but I’m not sure if that is a sensible approach.

image

Perhaps you are after the aspect option? You can set aspect=Makie.DataAspect() to see the difference.

Thanks @juliohm, based on my understanding aspect controls the ratio between the x and y axis, but I’m looking for range breaks in the x-axis. So I’m not sure how to achieve that with aspect

I’ve looked at the plotly example, and the breaks are not done by concatenating axes it seems, rather it appears to be a scale transform? So I tried the same, I define a scale function that maps 9-17 to 0-1, then the next day is 1-2, etc. It completely swallows the intervals in between so there must not be any data there.

x = reduce(vcat, [range(9, 17, length = 30) .+ i * 24 for i in 0:5])
y = cumsum(randn(length(x)))
color = repeat(1:6, inner = 30)
f = Figure()

xticks = reduce(vcat, [(10:2:16) .+ i * 24 for i in 0:5])
xticklabelrotation = pi/4
scatter(f[1, 1], x, y; color, axis = (; xticks, xticklabelrotation))

nine_to_five_forward(x) = (mod(x, 24) - 9) / (17 - 9) + fld(x, 24)
Makie.defaultlimits(::typeof(nine_to_five_forward)) = (9, 17)
Makie.defined_interval(::typeof(nine_to_five_forward)) = -Inf..Inf
nine_to_five_backward(x) = 24 * floor(x) + mod(x, 1) * (17 - 9) + 9
Makie.inverse_transform(::typeof(nine_to_five_forward)) = nine_to_five_backward

scatter(f[2, 1], x, y; color, axis = (; xticks, xticklabelrotation,
    xscale = nine_to_five_forward))
f

Thanks @Jules. This is very helpful. Can this kind of map work on DateTime types directly. Or do we work with Ints and then add tick labels (formatted DateTimes) afterwards?

Where did you find the Plotly example. I’m struggling to find the implementation

I didn’t find code, it just looked like a transform and not multiple axes.

I don’t know exactly how the datetime stuff is implemented now, probably you have to work with floats but if you know the conversion function then the logic should be doable on dates

@Jules Thanks for your example. I extended it to work with dates. Works great. Feel confident I can switch from Plotly now for my plotting needs. Which has served me well for many years but Makie is the way forward for me. Not as feature rich yet but way more performant and extensible. Great plotting package