Faster heatmap updates in jupyter notebook?


#1

I’ve got the following in a jupyter notebook:

using Plots
using Interact
gr()

@manipulate for row in 1:100, col in 1:100
    data = zeros(100,100)
    data[row,col] = 1
    heatmap(data)
end

which gives me a lovely dot with sliders, as expected:

Indeed, the dot even moves around when I move the sliders. Super cool! So now I’m getting greedy - when I move the sliders the plot flashes pretty ugly-ly and sometimes the sliders as well. Is there any smoother way to update the data in the heatmap?

In the past I’ve done some things with PlotlyJS for updating data smoothly because it’s more dynamic, but heatmap performance in PlotlyJS isn’t great, so I’m trying GR.

Any advice?


#2

As far as I can tell, I think you would have to improve the latency in the Jupyter messaging code if you want to get better interactivity.

Justification

I myself implemented/distributed a few notebooks with my InspectDR plotting tool. When you run it directly, InspectDR is quite fast. To see for yourself, simply plot one of the samples provided in the “https://github.com/ma-laforge/InspectDR.jl/tree/master/sample” directory.

If you run one of these examples, you can easily convince yourself that the response time is quite good. Simply use the mouse wheel to zoom in/out - or possibly shift+click+mousemove to drag the contents of the plot window.

However

If you take a look at some of my notebook examples, say the one provided in the following link:

Link: https://github.com/ma-laforge/InspectDR.jl/blob/master/notebook/2_interact.ipynb

You will notice that the update rate is significantly slower from the notebook when compared to the native response time of the GTK app. (Please refer to the “Interact/Reactive Control: Inspect/Gtk GUI” section at the end of the notebook).

Caveat

I have to admit that my argument above is not 100% accurate. The code path used to handle mouse events is not the exact same as the one used to handle Jupyter/interact code. However, the point is that I put alot of effort in making the code for InspectDR fast - and I still get very slow interact code.


#3

Where I might start

One possible explanation for this slow behaviour is that interact might be relaying too many messages to the plot backend. For example: when you drag a slider from 0% to 100%, it is possible that Interact does something exhaustive like send a signal for every pixel that the cursor gets dragged over.

Another possibility is that the signal pipeline for interact might simply be too slow for your application.

Thus: You might want to first benchmark the intearct code by logging which signals get sent out (ie how many signals are being sent when we drag the slider?).

It would also be nice to get some sort of reading of how big the latency is between when the mouse is moved, and when the signal finally gets updated in your code. Unfortunately: I don’t exactly know how one would do this.

I am sorry I cannot help more at this time, but I hope my suggestions can help nonetheless. I personally would also like to see better response times with the Interact package.


#4

Throttling definitely helped. The frame rate still isn’t great but it no longer causes the sliders to sometimes jump around (probably due to signal messages getting backed up and then old values are feeding back into the slider position. Here’s the code I’ve got now:

rowslider = slider(1:100)
colslider = slider(1:100)
display.([rowslider, colslider])
map(throttle(0.2, signal(rowslider)), throttle(0.2, signal(colslider))) do row, col
    data = zeros(100,100)
    data[row,col] = 1
    heatmap(data)
end

#5

Fast interactive updates are the achilles heel of Plots. Maybe try GR directly?


#6

To see whether the culprit is Plots or the jupyter notebook, you could maybe try doing it with InteractNext in a Blink window and see if it’s better.


#7

Performance seems about the same with Plots or raw GR.

It’s fast enough for what I’m doing, and I’m happy the code is simple (good for demos). I was just wondering if there’s low-hanging fruit for smoother animation, but it doesn’t seem so.

Makie is great for this sort of thing, but no webGL / notebook support yet. :wink: