This is code for a realtime updating Makie line plot. It is setup to let you pan the chart on click.
If you let it proceed to about +3 days from the start data point it draws a straight line from the first data point to the current and pan performance significantly drops.
Is this an issue with the DateTime axis or something deeper with Makie?
using Dates
using GLMakie
GLMakie.activate!()
Makie.inline!(false) # Probably unnecessary?
using Observables
function register_mouse_handlers(fig, ax, plot)
let
# Remove the rectangle zoom on left-click drag.
deregister_interaction!(ax, :rectanglezoom)
mouseevents = addmouseevents!(fig.scene)
global pos
global xmin
global xmax
global ymin
global ymax
global was_inside_plot = false
onmouseleftdrag(mouseevents) do event
if was_inside_plot
px_delta = event.px - pos
scale = extrema(ax.scene.px_area[])
dx = px_delta[1] * (xmax - xmin) / scale[2][1]
dy = -px_delta[2] * (ymax - ymin) / scale[2][2]
# Update the axis limits to achieve panning
xlims!(ax, xmin - dx, xmax - dx)
ylims!(ax, ymin + dy, ymax + dy)
end
end
onmouseleftdragstart(mouseevents) do event
global was_inside_plot = is_mouseinside(plot)
global pos = event.px
limits = extrema(ax.finallimits[])
global xmin, xmax = limits[1][1], limits[2][1]
global ymin, ymax = limits[1][2], limits[2][2]
end
onmouseleftdragstop(mouseevents) do event
global was_inside_plot = false
end
end
end
fig = Figure()
fig[1, 1] = chartgrid = GridLayout(tellwidth=false)
import PlotUtils: optimize_datetime_ticks
function get_timestamp_delta(timestamps)
return Dates.value.(timestamps) .- Dates.value(timestamps[1])
end
struct DateTimeTicks
t0::Dates.DateTime
end
function Makie.get_ticks(t::DateTimeTicks, any_scale, ::Makie.Automatic, vmin, vmax)
dateticks, dateticklabels = optimize_datetime_ticks(
Dates.value(Dates.DateTime(Dates.Millisecond(Int64(floor(vmin))) + t.t0)),
Dates.value(Dates.DateTime(Dates.Millisecond(Int64(ceil(vmax))) + t.t0)),
)
return dateticks .- Dates.value(t.t0), dateticklabels
end
timestamps = collect(Dates.now():Second(1):Dates.now())
t0 = timestamps[1]
timestamps = Observable(get_timestamp_delta(timestamps))
y = Observable([0.0])
ax = Axis(chartgrid[2, 1], xticks=DateTimeTicks(t0))
lineplot = lines!(ax, timestamps, y)
# Pan functionality
register_mouse_handlers(fig, ax, lineplot)
xlims!(ax, Dates.value(Millisecond(Minute(0))), Dates.value(Millisecond(Minute(60 * 12))))
ylims!(ax, -100, 100)
dt = t0
tm = Timer((timer) -> begin
for _ in 1:10000
push!(timestamps[], Dates.value(dt) - Dates.value(t0))
push!(y[], y[][end] + (rand() - 0.5))
global dt += Millisecond(250)
end
notify(timestamps)
notify(y)
yield()
end, 0.0, interval=0.25)
gl_screen = display(fig)
wait(gl_screen)