Is it possible to achieve zooming in a portion of an (already drawn) axis and display it as another axis, or as an inset?
Something like this in matplotlib:
Is it possible to achieve zooming in a portion of an (already drawn) axis and display it as another axis, or as an inset?
Something like this in matplotlib:
Yup this is possible, specifically using the BBox function (which specifies the bounding box of the Axis
). Here’s a small example:
using CairoMakie
CairoMakie.activate!(type = "svg")
x = 0.0 : 0.1 : 10.0
y = exp.(-x)
begin
fig = Figure(size=(800,800))
ax1 = Axis(
fig[1,1];
xgridvisible=false, ygridvisible=false
)
lines!(ax1, x, y)
bracket!(5, 0.01, 10, 0.01; offset=5, style=:square, orientation=:up)
ax2 = Axis(
fig;
yscale=log10,
bbox=BBox(400, 750, 200, 600)
)
lines!(ax2, x[50:end], y[50:end])
fig
end
This produces:
Hope this helps!
This here worked on GLMakie v0.8.11
(includes update of rectangle-zoom for interactivity). The idea is to turn this into something like an insetaxis
method, but I haven’t found time for that yet.
using GLMakie
import GLMakie.Makie.GeometryBasics: coordinates
GLMakie.activate!()
x = collect(1:100)
y = randn(length(x))
fig = Figure()
ax = Axis(fig[1,1])
inset = Axis(fig[1,1]; width=Relative(0.8), height=Relative(0.2),
halign=0.9, valign=0.1, backgroundcolor=(:white,1.0))
scatterlines!(ax, x, y)
subx, suby = x[30:40], y[30:40]
scatterlines!(inset, subx, suby)
poly!(ax, inset.finallimits, color=(:black,0), strokewidth=1, strokecolor=:black)
translate!(inset.blockscene, 0, 0, 1000)
shifted_bbox = lift(ax.scene.px_area, inset.layoutobservables.computedbbox,
ax.scene.camera.projectionview) do px_area, bbox, _
Rect2f(bbox.origin .- px_area.origin, bbox.widths)
end
scatter!(ax, shifted_bbox, color=:red, space=:pixel)
vert_edges = [ Observable{Any}() for _ = 1:4 ]
onany(inset.finallimits, shifted_bbox) do bbox1, bbox2
for (i,(c1, c2)) in enumerate(zip(coordinates(bbox1), coordinates(bbox2)))
cc1 = Makie.project(ax.scene, Point2f(c1))
vert_edges[i][] = [ cc1, Point2f(c2) ]
end
end
notify(inset.finallimits)
for vs in vert_edges
lines!(ax, vs, color=:grey, space=:pixel)
end
display(fig)
I don’t think this is what I need, because this example actually draws the data twice (which is what I am doing right now). It’s easy enough for a simple line plot, but if I have multiple layers, or even dynamically drawn axis, I would prefer to just use the data already in axis one.
This also draws the data twice, so not exactly what I am looking for.