Visitar URL original
[BUG]: contour with `xaxis.rangeslider` clips the main plot to the range slider's height (shared gap clipPath id) · Issue #8109 · plotly/plotly.js · GitHub
Skip to content

[BUG]: contour with xaxis.rangeslider clips the main plot to the range slider's height (shared gap clipPath id) #8109

Description

@YkRic

Description

When a contour trace is drawn with xaxis.rangeslider.visible: true, the main plot is clipped to a strip the height of the range slider. The rest of the subplot is blank. The range slider thumbnail itself renders correctly.

This happens with the default connectgaps: false, even when z has no missing values. Heatmaps are not affected.

Reproduced in 4.1.1 (latest), 4.0.0, 3.7.0, 3.0.0, 2.35.3 and 1.58.5 (Chrome, headless and desktop).

Cause. clipGaps in src/traces/contour/plot.js creates a single <clipPath> per trace, keyed only by trace.uid, and computes its path with the axes of the subplot currently being drawn:

function clipGaps(plotGroup, plotinfo, gd, cd0, perimeter) {
    var trace = cd0.trace;
    var clips = gd._fullLayout._clips;
    var clipId = 'clip' + trace.uid;
    // ... path computed with plotinfo.xaxis / plotinfo.yaxis
    Drawing.setClipUrl(plotGroup, clipId, gd);
}

The range slider draws the same trace again through rangePlot with its own small axes (isRangePlot: true). Both drawings share the same uid, so they share the same clipPath. The range plot is drawn last, so it overwrites the path with range-slider coordinates. The main plot then gets clipped by a shape that is only as tall as the slider.

In our measurements, the clip path bbox height equals the slider height (41px) instead of the plot area height (191px). Without the range slider, the clip path matches the plot area.

Screenshots/Video

Left: 4.1.1. Right: 4.1.1 with the one-line change below. Top row: full z. Bottom row: z with null cells.

Image

Steps to reproduce

<script src="https://cdn.plot.ly/plotly-4.1.1.js"></script>
<div id="graph" style="width:480px;height:420px"></div>
<script>
  var x = [0, 1, 2, 3, 4, 5];
  var y = [0, 1, 2, 3, 4];
  var z = y.map(function (j) { return x.map(function (i) { return 10 * (i + j); }); });

  Plotly.newPlot('graph', [{ type: 'contour', x: x, y: y, z: z }], {
    margin: { b: 90 },
    xaxis: { rangeslider: { visible: true } }
  });
</script>
  • Open the page.
  • Note that only a strip at the top of the main plot is drawn; the rest is blank.
  • The same happens after Plotly.restyle of x/y/z, after changing xaxis.range through the slider, and after relayout of a coloraxis.
  • With z containing nulls (e.g. [[10,20,30,40],[20,30,null,50],[30,null,50,60],[40,50,60,70]]), the main plot is clipped the same way. The gaps only show up correctly in the range-slider thumbnail.

Notes

Workarounds and why they fall short

  • connectgaps: true avoids the bug, because no clip path is created. But it changes the data: null cells get filled by interpolation, so the plot shows values that were never measured. That isn't acceptable when missing data must stay visible.
  • Disabling the range slider for contour traces is what we do for now.

Proposed fix (validated locally)

Give the range-plot drawing its own clip id:

 function clipGaps(plotGroup, plotinfo, gd, cd0, perimeter) {
     var trace = cd0.trace;
     var clips = gd._fullLayout._clips;
-    var clipId = 'clip' + trace.uid;
+    var clipId = 'clip' + trace.uid + (plotinfo.isRangePlot ? '-rangeplot' : '');

I applied the equivalent change to the 4.1.1 dist bundle and re-ran the cases above:

  • Full z, z with nulls, restyle of x/y/z, range change from the slider, coloraxis relayout, and a grid filled row by row (25% → 100%) all render correctly.
  • Gaps stay gaps in both the main plot and the thumbnail.
  • The main clip path matches the plot area height again.

The change above is a suggestion based on local testing; I haven't opened a PR. Feel free to use it if it fits.

Possibly related: #705 (2016, contour + range slider, "some <clipPath> node is not getting updated properly"). It was closed as a duplicate of #558 for lack of a repro.

Activity

  1. camdecoster commented on Oct 5, 2026

    @camdecoster
    Contributor

    Thanks for the report! Our team will take a look and follow up.

  2. self-assigned this
    on Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P2considered for next cyclebugsomething brokensize: 1

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions