Black Lives Matter. Please consider donating to Black Girls Code today.
Learn about the upcoming Dash Enterprise 4.0 release in the August 5th webinar with Chris Parmer, the Inventor of Dash.

Efficiently creating nearly identical scatterplots (r-shiny/javascript)

I have an application where user chooses some of ~10000 entries (genes), and displays xy marker+line scatterplot (time/expression), grouped by experiments & replicates.

This boils down to having identical number of traces (~50), identical x-coordinates, with only y-coordinates varying (and hovertext, which states trace-info and precise x, y coordinate).

Consequently, some 400 points per plot.
The plots are interactive on hover, click, and on manipulation from a custom-made shared legend. Through javascript events.

Plotting is implemented through R, but with plenty of javascript code handling the legend, and to improve performance.

I save plots to >generatedScatterPlots[[geneID]] = renderPlotly(…)< and complete the plotting through renderUI. Which at least achieves that previously generated plots are plotted in an instant.

What I’d like to solve:

  1. Plotting 10 genes takes 11-13 seconds. I’d like to achieve 3-4 sec.
  2. I am unable to plot a larger number of genes (~50), as I get segfault/cstack overflow in the R server.

Granted, I’m just testing this on my laptop, so server times would be better. But conceptually one should be able to improve upon this…

Ad 1)
Creating a single plot takes ~2.5sec.
Cloning the plotly svg’s 10 times takes ~1sec.
Using Plotly.restyle to change 10 plots to different y-values takes <3 sec.
Asking again for already generated 10 plots takes ~4sec.

Thus, it should be possible to either (I) reuse renderPlotly result, to just pass in same plotly ‘template’ (not to be confused with plotly template, i think), or (II) replicate the svg/html-widget in javascript. And restyle afterwards, to get a much faster plotting time.

I tried both approaches, none of them seems feasible. I know I cannot reuse an output binding. It would seem I cannot reuse renderFunction. [as in: template<-renderPlotly(…); output[[geneID1]]=template(); output[geneID2]]=template() ]
And replicating the plotly html-widget through jQuery ‘.clone()’ seems to miss out on listeners, properties… And even if I try to recover properties with Object.assign, and assume I somehow had the listeners come through… It does not seem to properly register with plotly (Plotly.restyle will fail on the cloned element; even if I deleted the previous one from DOM, to avoid nameclash or whatnot). I wouldn’t need it to register back to shiny, as all interaction is through javascript.

Ad 2)
Solving 1) seems to also solve 2), as there doesn’t seem to be an issue handling the duplicated DOM elements…

Any ideas? Am I missing out on something that could be used for this?