JuliaPlots / InspectDR.jl

Fast, interactive Julia/GTK+ plots (+Smith charts +Gtk widget +Cairo-only images)
MIT License
69 stars 9 forks source link

How to synchronize sub-plots #33

Open ufechner7 opened 2 years ago

ufechner7 commented 2 years ago

I have the following code:

# example for plotting in Julia using subplots
using Plots, Gtk.ShortNames, InspectDR

function init()
    inspectdr()
    InspectDR.defaults.xaxiscontrol_visible = false
    default(width=1, xtickfontsize=12, ytickfontsize=12, legendfontsize=12)
end

init()

x  = 0:0.01:100
y1 = sin.(x)
y2 = cos.(x)

p1 = plot(x, y1, link=:x, legend=false)
p2 = plot(x, y2, legend=false, color=:red)

pl = plot(p1, p2, layout=(2,1), legend = false)

pIDR = display(pl)            # Display with InspectDR and keep plot object
resize!(pIDR.wnd, 1200, 700)  # Resize GTK window directly
G_.keep_above(pIDR.wnd, true) # show the window on top
p = gui()
p.src.layout.values.ncolumns = 1 # Use 1 column only
InspectDR.refresh(p)
nothing

It works nicely, displaying two plots above each other, like in a 2 channel scope.

Now I want to be able to zoom into the time axes (x-axes). But I can only zoom one plot or the other.

How can I synchronize zoom factor (in x) and x-offset of both plots?

ma-laforge commented 2 years ago

😞 Trying to help solve your issue made me realize at which point InspectDR API has gotten confusing.

I should really revisit the entire architecture and clean up... but I don't see having time to do that in the near future.

Anyhow, let's look at solving your issue...

ma-laforge commented 2 years ago

InspectDR natively knows how to keep x-axes in sync... but not through the Plots.jl interface.

Plots.jl can arbitrarily link up x & y axes (though doesn't typically support zooming) - and InspectDR only supports linking up "y-strips" natively (allowing you to keep things in sync when zooming in).

To link up x-axes in InspectDR (as you requested), you need to access the specialized GraphStrip() objects (which are not typically manipulated directly by the user):

# example for plotting in Julia using subplots
using Plots, Gtk.ShortNames, InspectDR

function init()
    inspectdr()
    InspectDR.defaults.xaxiscontrol_visible = false
    default(width=1, xtickfontsize=12, ytickfontsize=12, legendfontsize=12)
end

init()

x  = 0:0.01:100
y1 = sin.(x)
y2 = cos.(x)

p = plot(x, y1, link=:x, legend=false)
#Add y2 to >>SAME<< plot:
plot!(p, x, y2, legend=false, color=:red)

#pIDR = display(p)            # Display with InspectDR and keep plot object
pIDR = gui() #Alternative to display(p)

#InspectDR direct manipulations----------------------------
sp1_IDR = pIDR.subplots[1].src #Reference to subplot 1
strip2 = InspectDR.GraphStrip()
push!(sp1_IDR.strips, strip2)
strip2.yscale = InspectDR.AxisScale(:lin)
data_orig = sp1_IDR.data
wfrm2 = sp1_IDR.data[2] #2nd waveform added to plot (assuming `Plots` maintains order).
wfrm2.strip=2 #Assign to a separate strip number
#EO InspectDR direct manipulations----------------------------

resize!(pIDR.wnd, 1200, 700)  # Resize GTK window directly
G_.keep_above(pIDR.wnd, true) # show the window on top
#Not necessary: p.src.layout.values.ncolumns = 1 # Use 1 column only
InspectDR.refresh(pIDR)
nothing
ma-laforge commented 2 years ago

But at this point, you might want to start using InspectDR directly (not using Plots.jl at all).

InspectDR-only solution

# example for plotting in Julia using subplots
using InspectDR, Gtk.ShortNames, Colors

function init()
    InspectDR.defaults.xaxiscontrol_visible = false
    #Plots.jl uses "sans-serif":
    InspectDR.overwritefont!(InspectDR.defaults.plotlayout, fontname="sans-serif")
    dlyt = InspectDR.defaults.plotlayout
    #Available: font_annotation, font_axislabel, font_legend, font_striplabel, font_ticklabel, font_time, font_title
    dlyt.font_title._size = 18
    dlyt.font_ticklabel._size = 12
    dlyt.font_legend._size = 12
end

init()

x  = 0:0.01:100
y1 = sin.(x)
y2 = cos.(x)
x  = collect(x) #InspectDR needs Vector{} (doesn't support ranges)

#Create a multi-strip plot:
plot1 = InspectDR.Plot2D(:lin, [:lin, :lin], title="Title",
    xlabel="x-label", ylabels=["y1-label", "y2-label"]
)
plot1.layout[:enable_legend] = false
wfrm = add(plot1, x, y1, strip=1, id="y1")
wfrm.line = line(style=:solid, width=2, color=colorant"blue")
wfrm = add(plot1, x, y2, strip=2, id="y2")
wfrm.line = line(style=:solid, width=2, color=colorant"red")

gtkplot = display(InspectDR.GtkDisplay(), plot1)
resize!(gtkplot.wnd, 1200, 700)  # Resize GTK window directly
G_.keep_above(gtkplot.wnd, true) # show the window on top
InspectDR.refresh(gtkplot) #Just in case
nothing
ma-laforge commented 2 years ago

Windows/Cairo font bug?

⚠️ Looks like there is a bug displaying fonts on windows (likely a bug in Cairo).

I've found that text will render as strange boxes if the font size is not "correct".

Ex:

image

I will likely have to open an issue on that.