Fastest way to draw on Gtk.jl 'canvas' with plots produced from Plots.jl?

IMO it’s not a good idea to “mix” plot packages. I’d define either

  • define the MPLBACKEND environment to switch to a Gtk backend in Matplotlib (please refer to the Matplotlib documentation), or
  • use plain GR and generate the heatmap within the GR framework as in this example:
using Gtk.ShortNames, Gtk.GConstants

using Printf
using GR

function plot(ctx, w, h)
    global sl

    ENV["GKS_WSTYPE"] = "142"
    ENV["GKSconid"] = @sprintf("%lu", UInt64(ctx.ptr))

    plt = gcf()
    plt[:size] = (w, h)
    nbins = Int64(Gtk.GAccessor.value(sl))

    heatmap(randn(nbins, nbins))
end

function draw(widget)
    ctx = Gtk.getgc(widget)
    w = Gtk.width(widget)
    h = Gtk.height(widget)

    Gtk.rectangle(ctx, 0, 0, w, h)
    Gtk.set_source_rgb(ctx, 1, 1, 1)
    Gtk.fill(ctx)

    plot(ctx, w, h)
end

function resize_event(widget)
    ctx = Gtk.getgc(widget)
    h = Gtk.height(widget)
    w = Gtk.width(widget)

    Gtk.paint(ctx)
end

function motion_notify_event(widget::Gtk.GtkCanvas, event::Gtk.GdkEventMotion)
    Gtk.GAccessor.text(lb, @sprintf("(%g, %g)", event.x, event.y))
end

function value_changed(widget::Gtk.GtkScale)
    global canvas
    draw(canvas)
end

win = Window("Gtk") |> (bx = Box(:v))
Gtk.set_gtk_property!(win, :double_buffered, false)
lb = Label("(-, -)")
sl = Scale(false, 10, 100, 1)
Gtk.GAccessor.value(sl, 30)
canvas = Canvas(600, 450)
push!(bx, lb, sl, canvas)

signal_connect(motion_notify_event, canvas, "motion-notify-event")
signal_connect(value_changed, sl, "value_changed")

canvas.resize = resize_event
canvas.draw = draw

Gtk.showall(win)

if !isinteractive()
    c = Condition()
    signal_connect(win, :destroy) do widget
        notify(c)
    end
    wait(c)
end
1 Like