Turn off interactivity/responsiveness in plotly/plotlyjs backend

What is the keyword to turn off the interactivity or responsiveness in the plotly backend for the Plots backend in Julia?

For reference, I am using Pluto and while the interactivity is great, I am doing some very dense scatter plots (>1000 points) with a great number of subplots (>100). The default hover and interactivity features end up consuming a lot of memory when the HTML is displayed (with the saved HTML files themselves being over 50 MB in size). This causes Chrome/Safari to crash.

I am looking for a way to turn off the interactivity. For various reasons (documented here and here) I am stuck with using the plotly backend (I figured out how to save to PDF, but I also want to save to HTML; albeit with interactivity turned off).

I tried keywords like static=true or responsive=false etc. but it didn’t work. Using hover=false turned off the tooltip but not the rest of the interactivity.

If you’re happy to use plotly directly (without the extra code of the Plots package) then you can use plotly code inside Pluto with the PlutoPlotly.jl package. There are certain customisable attributes that you can control directly, such as for
subplots,

Subplots

Parameters (from PlotlyBase.jl/src/subplot_utils/)

  • rows: Number of rows in the subplot grid. Must be greater than zero.
  • cols: Number of columns in the subplot grid. Must be greater than zero.
  • shared_xaxes: Assign shared (linked) x-axes for 2D cartesian subplots
    • true or “columns”: Share axes among subplots in the same column
    • “rows”: Share axes among subplots in the same row
    • “all”: Share axes across all subplots in the grid
  • shared_yaxes: Assign shared (linked) y-axes for 2D cartesian subplots
    • “columns”: Share axes among subplots in the same column
    • true or “rows”: Share axes among subplots in the same row
    • “all”: Share axes across all subplots in the grid.
  • start_cell: Choose the starting cell in the subplot grid used to set the domains_grid of the subplots.
    • “top-left”: Subplots are numbered with (1, 1) in the top left corner
    • “bottom-left”: Subplots are numbererd with (1, 1) in the bottom left corner
  • horizontal_spacing: Space between subplot columns in normalized plot coordinates. Must be a float between 0 and 1. Applies to all columns (use “specs” subplot-dependents spacing)
  • vertical_spacing: Space between subplot rows in normalized plot coordinates. Must be a float between 0 and 1. Applies to all rows (use “specs” subplot-dependents spacing)
  • subplot_titles: Title of each subplot as a list in row-major ordering. Empty strings (“”) can be included in the list if no subplot title is desired in that space so that the titles are properly indexed.
  • specs: Per subplot specifications of subplot type, row/column spanning, and spacing.
    • The number of rows in “specs” must be equal to “rows”.
    • The number of columns in “specs”
    • Each item in the “specs” list corresponds to one subplot
      in a subplot grid. (N.B. The subplot grid has exactly “rows”
      times “cols” cells.)
    • Use missing for a blank a subplot cell (or to move past a col/row span).
    • Each item in “specs” is an instance of Spec. See docs for Spec for more information
    • Note: Use horizontal_spacing and vertical_spacing to adjust the spacing in between the subplots.
  • insets: Inset specifications. Insets are subplots that overlay grid subplots
    • Each item in “insets” is an instance of Inset. See docs for Inset for more info
  • column_widths: Array of length cols of the relative widths of each column of suplots. Values are normalized internally and used to distribute overall width of the figure (excluding padding) among the columns.
  • row_heights: Array of length rows of the relative heights of each row of subplots. Values are normalized internally and used to distribute overall height of the figure (excluding padding) among the rows
  • column_titles: list of length cols of titles to place above the top subplot in each column.
  • row_titles: list of length rows of titles to place on the right side of each row of subplots.
  • x_title: Title to place below the bottom row of subplots, centered horizontally
  • y_title: Title to place to the left of the left column of subplots, centered vertically

and overall plot configuration

PlotConfig

PlotConfig(;kwargs…) (from PlotlyBase/src/plot_config.jl

Configuration options to be sent to the frontend to control aspects of how the plot is rendered. The acceptable keyword arguments are:

  • scrollZoom: Determines whether mouse wheel or two-finger scroll zooms is enable. Turned on by default for gl3d, geo and mapbox subplots (as these subplot types do not have zoombox via pan), but turned off by default for cartesian subplots. Set scrollZoom to false to disable scrolling for all subplots.

  • editable: Determines whether the graph is editable or not. Sets all pieces of edits unless a separate edits config item overrides individual parts.

  • staticPlot: Determines whether the graphs are interactive or not. If false, no interactivity, for export or image generation.

  • toImageButtonOptions: Statically override options for toImage modebar button allowed keys are format, filename, width, height

  • displayModeBar: Determines the mode bar display mode. If true, the mode bar is always visible. If false, the mode bar is always hidden. If hover, the mode bar is visible while the mouse cursor is on the graph container.

  • modeBarButtonsToRemove: Remove mode bar buttons by name

  • modeBarButtonsToAdd: Add mode bar button using config objects. To enable predefined modebar buttons e.g. shape drawing, hover and spikelines, simply provide their string name(s). This could include: v1hovermode, hoverclosest, hovercompare, togglehover, togglespikelines, drawline, drawopenpath, drawclosedpath, drawcircle, drawrect and eraseshape. Please note that these predefined buttons will only be shown if they are compatible with all trace types used in a graph.

  • modeBarButtons: Define fully custom mode bar buttons as nested array where the outer arrays represents button groups, and the inner arrays have buttons config objects or names of default buttons.

  • showLink: Determines whether a link to Chart Studio Cloud is displayed at the bottom right corner of resulting graphs. Use with sendData and linkText.

  • plotlyServerURL: When set it determines base URL for the ‘Edit in Chart Studio’ showEditInChartStudio/showSendToCloud mode bar button and the showLink/sendData on-graph link. To enable sending your data to Chart Studio Cloud, you need to set both plotlyServerURL to ‘https://chart-studio.plotly.com’ and also set showSendToCloud to true.

  • linkText: Sets the text appearing in the showLink link.

  • showEditInChartStudio: Same as showSendToCloud, but use a pencil icon instead of a floppy-disk. Note that if both showSendToCloud and showEditInChartStudio are turned, only showEditInChartStudio will be honored.

  • locale: Which localization should we use? Should be a string like ‘en’ or ‘en-US’.

  • displaylogo: Determines whether or not the plotly logo is displayed on the end of the mode bar.

  • responsive: Determines whether to change the layout size when window is resized.

  • doubleClickDelay: Sets the delay for registering a double-click in ms. This is the time interval (in ms) between first mousedown and 2nd mouseup to constitute a double-click. This setting propagates to all on-subplot double clicks (except for geo and mapbox) and on-legend double clicks.

including the option staticPlot that turns off interactivity.
Here is an example that can be run in a Pluto notebook:

using PlutoPlotly
d = 5; # number of (random) datapoints
N = 6; # grid size N x N
begin
	fig=Plot(Layout(template=templates.plotly_dark,
			Subplots(rows=N, cols=N,
						shared_xaxes=true, shared_yaxes=true)), 
		config=PlotlyBase.PlotConfig(staticPlot=true)
	)
	for row in 1:N for col in 1:N
		add_trace!(fig,
				scatter(x=1:d, y=rand(d), showlegend=false),
				row=row, col=col,
		)
	end end
	PlutoPlot(fig) # This is the `plot` function from PlutoPlotly, not from PlotlyJS
end
2 Likes

For very dense scatter traces you can also try using the scattergl type instead of the usual scatter as it uses WebGL for rendering which should be significantly faster for a large number of points (Plotly.js performance when data points reaching 180k - plotly.js - Plotly Community Forum).

If that is not already the way you managed to save plots to pdf, consider having a look at GitHub - JuliaPlots/PlotlyKaleido.jl which is a lightweight addition to have multiple format saving for plotlyjs plots.

If you eventually end up trying PlutoPlotly (it is more optimized for Pluto, but I am the developer so I might be biased :D), for the time being you have to call savefig from PlotlyKaleido on the Plot object that is contained insode the PlutoPlot one.
So in the example provided above by @jd-foster, you’d want to call savefig(fig).

I just opened an issue to add this functionality in PlutoPlotly directly but I don’t have time in the next days

2 Likes