Add custom size legend to scatterPlot when point size encodes a numeric column#293
Conversation
|
@copilot Remove the margin adjustment, as it doesn't help anything. In addition, when used with the color legend, they heavily overlap and need to be positioned:
While I don't expect perfection, try to better offset them vertically. In addition, the legend annotations seem to be doubled, i.e. the text annotations are duplicated in the exact same position, which is annoying when trying to reposition as the top one has to be deleted first. Lastly, the color legend title includes both the color and size variables (rather than just the color variable). |
Addressed in d8... (latest commits):
Verified the de-duplication, title stripping, and offset behaviors with plotly and added regression tests. |
|
@copilot the custom size legend title tends to be horizontally offset to a degree where it's sometimes not visible on the plot area:
In addition, the text for each marker can sometimes be rather far from the actual markers depending on plot re-sizing (e.g. when the plot is very wide). Lastly, when the plot is made more narrow, the size legend can overlap the plot area, requiring manual movement of all markers and text for the legend:
Either dynamically keep the legend from the edge of a plot area in a sensible way, OR, perhaps more simply, provide a "start_x" parameter to |
Added a |
|
@copilot Make |
Done in 0f3b70d. Added a "Size Legend Y Position" input (default 0.95) to both the scatterPlot and DotPlot modules, wired to |
|
@copilot try to scale the size legend marker text label spacing from the actual marker by a specific value rather than a relative one (or calculate the relative distance based on total plot width). Currently, it requires manual adjustment based on plot width (when wide, needs to be brought closer, when narrow, the opposite). |
Done in e1fb2d0. The numeric labels are now anchored at each circle's x in paper space but offset purely in pixels via the annotation |
|
Closes #10. |



plotly cannot render a native legend when marker size is mapped to a numeric variable (plotly.R#705), so the scatterPlot module silently dropped size-encoding information. This ports the manual circle legend already used by the DotPlot module to scatterPlot.
UI (
dittoViz_ScatterPlot_module_ui.R)dittoViz::scatterPlot()'ssizeaccepts a number or a column name.1.02) that nudges the whole custom size legend along the x-axis, wired to thestart_xargument of.custom_legend().0.95) that nudges the whole custom size legend along the y-axis, wired to thestart_yargument of.custom_legend().Server (
dittoViz_ScatterPlot_module_server.R)sizeargument resolves to the selected column whensize.byis set, else the numeric Point Size:.custom_legend()helper, which derives circle breaks from the plotted marker sizes (no-op whensize.byis unset)..custom_legend()'sstart_x/start_yso users can reposition the legend horizontally (when it overflows a narrow plot or drifts on a wide one) and vertically (to offset it from an overlapping color/shape legend). The earlier categorical auto-offset ofstart_ywas removed in favor of the explicit input.DotPlot module (
plotthis_DotPlot_module_ui.R,plotthis_DotPlot_module_server.R)0.95) wired to.custom_legend()'sstart_y, alongside the existing "Size Legend X Position" input, with matching reset handling..custom_legend()helper (plot_mods.R)start_yparameter (default0.95) controls where the legend column begins, allowing the caller to vertically offset it from an overlapping color/shape legend; invalid values fall back to the default.start_xparameter (default1.02) anchors the legend column (circles, labels, and title) horizontally so the whole set can be nudged along the x-axis; invalid values fall back to the default.x_pos + 0.02instead ofx_pos + 0.1) so it no longer drifts off the plot area.xshift(measured in pixels) rather than a relative paper-space offset. This keeps the marker-to-label spacing constant regardless of plot width, instead of drifting away from the markers on wide plots and crowding them on narrow ones.add_annotations(). This fixes label annotations being duplicated at the same position (and prevents re-duplication by laterplotly_build()calls).color<br />size); the helper now strips the size variable from that combined title so the color legend shows only the color variable.Notes
size.min/size.maxare intentionally not implemented:dittoViz::scatterPlot()exposes no size-range parameter (unlike plotthisDotPlot), so honoring them would require post-hoc rescaling of marker sizes — better addressed upstream and flagged as non-critical in the issue.tests/testthat/test-scatterPlot.R, plus.custom_legendregression tests intests/testthat/test-plot_mods.Rcovering de-duplication, title stripping, thestart_yoffset (including invalid-value fallback), thestart_xhorizontal shift (including invalid-value fallback), and the fixed pixel-based labelxshift(left-anchored, positive, and growing with glyph size);man/regenerated via roxygen2.