plotly / plotly/plotly.js

[BUG] Colorbar thickness becomes too wide (~16k px) when marker.colorbar.thicknessmode='pixels' is applied via Plotly.restyle

Ouverte
#8,012 3 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

bug P3 size: 1
Langage dominant
JavaScript
Étoiles
18.3k
Forks
2k
Merge moyen
2 j 12 h
PR mergées (30 j)
28

Description

Description

For a splom trace whose marker.colorbar exists but has no explicit thickness
(plotly.js defaults it), applying marker.colorbar.thicknessmode='pixels' afterwards with
Plotly.restyle collapses the whole splom layout:

  • plotly.js silently writes thickness: 16290 back into the user-visible trace
    (gd.data[1].marker.colorbar.thickness),
  • the colorbar then occupies ~16k px and the splom panels shrink from ~125 px to ~15 px per axis.

Setting the exact same value at newPlot time (Path A in the repro) renders fine.

Reproduced on every version I could test: 2.35.2, 3.5.0, 3.5.1, and current 3.8.2.

Steps to reproduce

Save the following as index.html and open it in a browser
(uses https://cdn.plot.ly/plotly-3.5.0.min.js; the bundled copy from any release works too).
The page renders both paths, then prints the colorbar object and the panel width under each plot.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>plotly.js splom + marker.colorbar restyle bug</title>
<!-- any plotly.js >= 2.35 works: use your own bundle or the CDN below -->
<script src="https://cdn.plot.ly/plotly-3.5.0.min.js"></script>
<style>
  body { font-family: -apple-system, "Segoe UI", Roboto, sans-serif; margin: 16px; }
  .row { display: flex; gap: 12px; align-items: flex-start; flex-wrap: wrap; }
  h3 { margin: 10px 0 4px; font-size: 15px; }
  pre { background: #f6f8fa; border-radius: 6px; padding: 10px; font-size: 12px;
        white-space: pre-wrap; max-width: 780px; }
  code { background: #f6f8fa; padding: 1px 4px; border-radius: 4px; }
</style>
</head>
<body>
<h1>splom layout collapses when <code>marker.colorbar.thicknessmode='pixels'</code>
is applied with <code>Plotly.restyle</code></h1>
<p>Same data + layout, same final <code>marker.colorbar</code> value. Difference is only <b>when</b>
it is applied:</p>
<ul>
  <li><b>Path A (normal):</b> <code>marker.colorbar = {thicknessmode: 'pixels'}</code> is in the
      figure at <code>newPlot</code> time.</li>
  <li><b>Path B (collapsed):</b> figure starts with <code>marker.colorbar = {}</code> (no explicit
      <code>thickness</code>), then <code>Plotly.restyle(gd, {'marker.colorbar.thicknessmode':'pixels'}, [1])</code>.</li>
</ul>
<p>After Path B, plotly.js writes <b>thickness: 16290</b> back into the trace's colorbar and the
splom panels collapse from ~125px to ~15px per axis.</p>

<div class="row">
  <div>
    <h3>Path A — set at newPlot time (normal)</h3>
    <div id="A" class="gd" style="width:750px;height:900px"></div>
    <pre id="mA">…</pre>
  </div>
  <div>
    <h3>Path B — set via Plotly.restyle (collapsed)</h3>
    <div id="B" class="gd" style="width:750px;height:900px"></div>
    <pre id="mB">…</pre>
  </div>
</div>

<script>
var DATA = [{"dimensions": [{"axis": {"matches": true}, "label": "sepal_length", "values": {"dtype": "f8", "bdata": "ZmZmZmZmFECamZmZmZkTQM3MzMzMzBJAZmZmZmZmEkAAAAAAAAAUQJqZmZmZmRVAZmZmZmZmEkAAAAAAAAAUQJqZmZmZmRFAmpmZmZmZE0CamZmZmZkVQDMzMzMzMxNAMzMzMzMzE0AzMzMzMzMRQDMzMzMzMxdAzczMzMzMFkCamZmZmZkVQGZmZmZmZhRAzczMzMzMFkBmZmZmZmYUQJqZmZmZmRVAZmZmZmZmFEBmZmZmZmYSQGZmZmZmZhRAMzMzMzMzE0AAAAAAAAAUQAAAAAAAABRAzczMzMzMFEDNzMzMzMwUQM3MzMzMzBJAMzMzMzMzE0CamZmZmZkVQM3MzMzMzBRAAAAAAAAAFkCamZmZmZkTQAAAAAAAABRAAAAAAAAAFkCamZmZmZkTQJqZmZmZmRFAZmZmZmZmFEAAAAAAAAAUQAAAAAAAABJAmpmZmZmZEUAAAAAAAAAUQGZmZmZmZhRAMzMzMzMzE0BmZmZmZmYUQGZmZmZmZhJAMzMzMzMzFUAAAAAAAAAUQA=="}}, {"axis": {"matches": true}, "label": "sepal_width", "values": {"dtype": "f8", "bdata": "AAAAAAAADEAAAAAAAAAIQJqZmZmZmQlAzczMzMzMCEDNzMzMzMwMQDMzMzMzMw9AMzMzMzMzC0AzMzMzMzMLQDMzMzMzMwdAzczMzMzMCECamZmZmZkNQDMzMzMzMwtAAAAAAAAACEAAAAAAAAAIQAAAAAAAABBAmpmZmZmZEUAzMzMzMzMPQAAAAAAAAAxAZmZmZmZmDkBmZmZmZmYOQDMzMzMzMwtAmpmZmZmZDUDNzMzMzMwMQGZmZmZmZgpAMzMzMzMzC0AAAAAAAAAIQDMzMzMzMwtAAAAAAAAADEAzMzMzMzMLQJqZmZmZmQlAzczMzMzMCEAzMzMzMzMLQGZmZmZmZhBAzczMzMzMEEDNzMzMzMwIQJqZmZmZmQlAAAAAAAAADEDNzMzMzMwIQAAAAAAAAAhAMzMzMzMzC0AAAAAAAAAMQGZmZmZmZgJAmpmZmZmZCUAAAAAAAAAMQGZmZmZmZg5AAAAAAAAACEBmZmZmZmYOQJqZmZmZmQlAmpmZmZmZDUBmZmZmZmYKQA=="}}, {"axis": {"matches": true}, "label": "petal_length", "values": {"dtype": "f8", "bdata": "ZmZmZmZm9j9mZmZmZmb2P83MzMzMzPQ/AAAAAAAA+D9mZmZmZmb2PzMzMzMzM/s/ZmZmZmZm9j8AAAAAAAD4P2ZmZmZmZvY/AAAAAAAA+D8AAAAAAAD4P5qZmZmZmfk/ZmZmZmZm9j+amZmZmZnxPzMzMzMzM/M/AAAAAAAA+D/NzMzMzMz0P2ZmZmZmZvY/MzMzMzMz+z8AAAAAAAD4PzMzMzMzM/s/AAAAAAAA+D8AAAAAAADwPzMzMzMzM/s/ZmZmZmZm/j+amZmZmZn5P5qZmZmZmfk/AAAAAAAA+D9mZmZmZmb2P5qZmZmZmfk/mpmZmZmZ+T8AAAAAAAD4PwAAAAAAAPg/ZmZmZmZm9j8AAAAAAAD4PzMzMzMzM/M/zczMzMzM9D8AAAAAAAD4P83MzMzMzPQ/AAAAAAAA+D/NzMzMzMz0P83MzMzMzPQ/zczMzMzM9D+amZmZmZn5P2ZmZmZmZv4/ZmZmZmZm9j+amZmZmZn5P2ZmZmZmZvY/AAAAAAAA+D9mZmZmZmb2Pw=="}}, {"axis": {"matches": true}, "label": "petal_width", "values": {"dtype": "f8", "bdata": "mpmZmZmZyT+amZmZmZnJP5qZmZmZmck/mpmZmZmZyT+amZmZmZnJP5qZmZmZmdk/MzMzMzMz0z+amZmZmZnJP5qZmZmZmck/mpmZmZmZuT+amZmZmZnJP5qZmZmZmck/mpmZmZmZuT+amZmZmZm5P5qZmZmZmck/mpmZmZmZ2T+amZmZmZnZPzMzMzMzM9M/MzMzMzMz0z8zMzMzMzPTP5qZmZmZmck/mpmZmZmZ2T+amZmZmZnJPwAAAAAAAOA/mpmZmZmZyT+amZmZmZnJP5qZmZmZmdk/mpmZmZmZyT+amZmZmZnJP5qZmZmZmck/mpmZmZmZyT+amZmZmZnZP5qZmZmZmbk/mpmZmZmZyT+amZmZmZm5P5qZmZmZmck/mpmZmZmZyT+amZmZmZm5P5qZmZmZmck/mpmZmZmZyT8zMzMzMzPTPzMzMzMzM9M/mpmZmZmZyT8zMzMzMzPjP5qZmZmZmdk/MzMzMzMz0z+amZmZmZnJP5qZmZmZmck/mpmZmZmZyT+amZmZmZnJPw=="}}], "hovertemplate": "species=setosa<br>%{xaxis.title.text}=%{x}<br>%{yaxis.title.text}=%{y}<extra></extra>", "legendgroup": "setosa", "marker": {"color": "#636efa", "symbol": "circle"}, "name": "setosa", "showlegend": true, "type": "splom"}, {"dimensions": [{"axis": {"matches": true}, "label": "sepal_length", "values": {"dtype": "f8", "bdata": "AAAAAAAAHECamZmZmZkZQJqZmZmZmRtAAAAAAAAAFkAAAAAAAAAaQM3MzMzMzBZAMzMzMzMzGUCamZmZmZkTQGZmZmZmZhpAzczMzMzMFEAAAAAAAAAUQJqZmZmZmRdAAAAAAAAAGEBmZmZmZmYYQGZmZmZmZhZAzczMzMzMGkBmZmZmZmYWQDMzMzMzMxdAzczMzMzMGEBmZmZmZmYWQJqZmZmZmRdAZmZmZmZmGEAzMzMzMzMZQGZmZmZmZhhAmpmZmZmZGUBmZmZmZmYaQDMzMzMzMxtAzczMzMzMGkAAAAAAAAAYQM3MzMzMzBZAAAAAAAAAFkAAAAAAAAAWQDMzMzMzMxdAAAAAAAAAGECamZmZmZkVQAAAAAAAABhAzczMzMzMGkAzMzMzMzMZQGZmZmZmZhZAAAAAAAAAFkAAAAAAAAAWQGZmZmZmZhhAMzMzMzMzF0AAAAAAAAAUQGZmZmZmZhZAzczMzMzMFkDNzMzMzMwWQM3MzMzMzBhAZmZmZmZmFEDNzMzMzMwWQA=="}}, {"axis": {"matches": true}, "label": "sepal_width", "values": {"dtype": "f8", "bdata": "mpmZmZmZCUCamZmZmZkJQM3MzMzMzAhAZmZmZmZmAkBmZmZmZmYGQGZmZmZmZgZAZmZmZmZmCkAzMzMzMzMDQDMzMzMzMwdAmpmZmZmZBUAAAAAAAAAAQAAAAAAAAAhAmpmZmZmZAUAzMzMzMzMHQDMzMzMzMwdAzczMzMzMCEAAAAAAAAAIQJqZmZmZmQVAmpmZmZmZAUAAAAAAAAAEQJqZmZmZmQlAZmZmZmZmBkAAAAAAAAAEQGZmZmZmZgZAMzMzMzMzB0AAAAAAAAAIQGZmZmZmZgZAAAAAAAAACEAzMzMzMzMHQM3MzMzMzARAMzMzMzMzA0AzMzMzMzMDQJqZmZmZmQVAmpmZmZmZBUAAAAAAAAAIQDMzMzMzMwtAzczMzMzMCEBmZmZmZmYCQAAAAAAAAAhAAAAAAAAABEDNzMzMzMwEQAAAAAAAAAhAzczMzMzMBEBmZmZmZmYCQJqZmZmZmQVAAAAAAAAACEAzMzMzMzMHQDMzMzMzMwdAAAAAAAAABEBmZmZmZmYGQA=="}}, {"axis": {"matches": true}, "label": "petal_length", "values": {"dtype": "f8", "bdata": "zczMzMzMEkAAAAAAAAASQJqZmZmZmRNAAAAAAAAAEEBmZmZmZmYSQAAAAAAAABJAzczMzMzMEkBmZmZmZmYKQGZmZmZmZhJAMzMzMzMzD0AAAAAAAAAMQM3MzMzMzBBAAAAAAAAAEEDNzMzMzMwSQM3MzMzMzAxAmpmZmZmZEUAAAAAAAAASQGZmZmZmZhBAAAAAAAAAEkAzMzMzMzMPQDMzMzMzMxNAAAAAAAAAEECamZmZmZkTQM3MzMzMzBJAMzMzMzMzEUCamZmZmZkRQDMzMzMzMxNAAAAAAAAAFEAAAAAAAAASQAAAAAAAAAxAZmZmZmZmDkCamZmZmZkNQDMzMzMzMw9AZmZmZmZmFEAAAAAAAAASQAAAAAAAABJAzczMzMzMEkCamZmZmZkRQGZmZmZmZhBAAAAAAAAAEECamZmZmZkRQGZmZmZmZhJAAAAAAAAAEEBmZmZmZmYKQM3MzMzMzBBAzczMzMzMEEDNzMzMzMwQQDMzMzMzMxFAAAAAAAAACEBmZmZmZmYQQA=="}}, {"axis": {"matches": true}, "label": "petal_width", "values": {"dtype": "f8", "bdata": "ZmZmZmZm9j8AAAAAAAD4PwAAAAAAAPg/zczMzMzM9D8AAAAAAAD4P83MzMzMzPQ/mpmZmZmZ+T8AAAAAAADwP83MzMzMzPQ/ZmZmZmZm9j8AAAAAAADwPwAAAAAAAPg/AAAAAAAA8D9mZmZmZmb2P83MzMzMzPQ/ZmZmZmZm9j8AAAAAAAD4PwAAAAAAAPA/AAAAAAAA+D+amZmZmZnxP83MzMzMzPw/zczMzMzM9D8AAAAAAAD4PzMzMzMzM/M/zczMzMzM9D9mZmZmZmb2P2ZmZmZmZvY/MzMzMzMz+z8AAAAAAAD4PwAAAAAAAPA/mpmZmZmZ8T8AAAAAAADwPzMzMzMzM/M/mpmZmZmZ+T8AAAAAAAD4P5qZmZmZmfk/AAAAAAAA+D/NzMzMzMz0P83MzMzMzPQ/zczMzMzM9D8zMzMzMzPzP2ZmZmZmZvY/MzMzMzMz8z8AAAAAAADwP83MzMzMzPQ/MzMzMzMz8z/NzMzMzMz0P83MzMzMzPQ/mpmZmZmZ8T/NzMzMzMz0Pw=="}}], "hovertemplate": "species=versicolor<br>%{xaxis.title.text}=%{x}<br>%{yaxis.title.text}=%{y}<extra></extra>", "legendgroup": "versicolor", "marker": {"color": "#EF553B", "symbol": "circle"}, "name": "versicolor", "showlegend": true, "type": "splom"}, {"dimensions": [{"axis": {"matches": true}, "label": "sepal_length", "values": {"dtype": "f8", "bdata": "MzMzMzMzGUAzMzMzMzMXQGZmZmZmZhxAMzMzMzMzGUAAAAAAAAAaQGZmZmZmZh5AmpmZmZmZE0AzMzMzMzMdQM3MzMzMzBpAzczMzMzMHEAAAAAAAAAaQJqZmZmZmRlAMzMzMzMzG0DNzMzMzMwWQDMzMzMzMxdAmpmZmZmZGUAAAAAAAAAaQM3MzMzMzB5AzczMzMzMHkAAAAAAAAAYQJqZmZmZmRtAZmZmZmZmFkDNzMzMzMweQDMzMzMzMxlAzczMzMzMGkDNzMzMzMwcQM3MzMzMzBhAZmZmZmZmGECamZmZmZkZQM3MzMzMzBxAmpmZmZmZHUCamZmZmZkfQJqZmZmZmRlAMzMzMzMzGUBmZmZmZmYYQM3MzMzMzB5AMzMzMzMzGUCamZmZmZkZQAAAAAAAABhAmpmZmZmZG0DNzMzMzMwaQJqZmZmZmRtAMzMzMzMzF0AzMzMzMzMbQM3MzMzMzBpAzczMzMzMGkAzMzMzMzMZQAAAAAAAABpAzczMzMzMGECamZmZmZkXQA=="}}, {"axis": {"matches": true}, "label": "sepal_width", "values": {"dtype": "f8", "bdata": "ZmZmZmZmCkCamZmZmZkFQAAAAAAAAAhAMzMzMzMzB0AAAAAAAAAIQAAAAAAAAAhAAAAAAAAABEAzMzMzMzMHQAAAAAAAAARAzczMzMzMDECamZmZmZkJQJqZmZmZmQVAAAAAAAAACEAAAAAAAAAEQGZmZmZmZgZAmpmZmZmZCUAAAAAAAAAIQGZmZmZmZg5AzczMzMzMBECamZmZmZkBQJqZmZmZmQlAZmZmZmZmBkBmZmZmZmYGQJqZmZmZmQVAZmZmZmZmCkCamZmZmZkJQGZmZmZmZgZAAAAAAAAACEBmZmZmZmYGQAAAAAAAAAhAZmZmZmZmBkBmZmZmZmYOQGZmZmZmZgZAZmZmZmZmBkDNzMzMzMwEQAAAAAAAAAhAMzMzMzMzC0DNzMzMzMwIQAAAAAAAAAhAzczMzMzMCEDNzMzMzMwIQM3MzMzMzAhAmpmZmZmZBUCamZmZmZkJQGZmZmZmZgpAAAAAAAAACEAAAAAAAAAEQAAAAAAAAAhAMzMzMzMzC0AAAAAAAAAIQA=="}}, {"axis": {"matches": true}, "label": "petal_length", "values": {"dtype": "f8", "bdata": "AAAAAAAAGEBmZmZmZmYUQJqZmZmZmRdAZmZmZmZmFkAzMzMzMzMXQGZmZmZmZhpAAAAAAAAAEkAzMzMzMzMZQDMzMzMzMxdAZmZmZmZmGEBmZmZmZmYUQDMzMzMzMxVAAAAAAAAAFkAAAAAAAAAUQGZmZmZmZhRAMzMzMzMzFUAAAAAAAAAWQM3MzMzMzBpAmpmZmZmZG0AAAAAAAAAUQM3MzMzMzBZAmpmZmZmZE0DNzMzMzMwaQJqZmZmZmRNAzczMzMzMFkAAAAAAAAAYQDMzMzMzMxNAmpmZmZmZE0BmZmZmZmYWQDMzMzMzMxdAZmZmZmZmGECamZmZmZkZQGZmZmZmZhZAZmZmZmZmFEBmZmZmZmYWQGZmZmZmZhhAZmZmZmZmFkAAAAAAAAAWQDMzMzMzMxNAmpmZmZmZFUBmZmZmZmYWQGZmZmZmZhRAZmZmZmZmFECamZmZmZkXQM3MzMzMzBZAzczMzMzMFEAAAAAAAAAUQM3MzMzMzBRAmpmZmZmZFUBmZmZmZmYUQA=="}}, {"axis": {"matches": true}, "label": "petal_width", "values": {"dtype": "f8", "bdata": "AAAAAAAABEBmZmZmZmb+P83MzMzMzABAzczMzMzM/D+amZmZmZkBQM3MzMzMzABAMzMzMzMz+z/NzMzMzMz8P83MzMzMzPw/AAAAAAAABEAAAAAAAAAAQGZmZmZmZv4/zczMzMzMAEAAAAAAAAAAQDMzMzMzMwNAZmZmZmZmAkDNzMzMzMz8P5qZmZmZmQFAZmZmZmZmAkAAAAAAAAD4P2ZmZmZmZgJAAAAAAAAAAEAAAAAAAAAAQM3MzMzMzPw/zczMzMzMAEDNzMzMzMz8P83MzMzMzPw/zczMzMzM/D/NzMzMzMwAQJqZmZmZmfk/ZmZmZmZm/j8AAAAAAAAAQJqZmZmZmQFAAAAAAAAA+D9mZmZmZmb2P2ZmZmZmZgJAMzMzMzMzA0DNzMzMzMz8P83MzMzMzPw/zczMzMzMAEAzMzMzMzMDQGZmZmZmZgJAZmZmZmZm/j9mZmZmZmYCQAAAAAAAAARAZmZmZmZmAkBmZmZmZmb+PwAAAAAAAABAZmZmZmZmAkDNzMzMzMz8Pw=="}}], "hovertemplate": "species=virginica<br>%{xaxis.title.text}=%{x}<br>%{yaxis.title.text}=%{y}<extra></extra>", "legendgroup": "virginica", "marker": {"color": "#00cc96", "symbol": "circle"}, "name": "virginica", "showlegend": true, "type": "splom"}];
var LAYOUT = {"legend": {"title": {"text": "species"}, "tracegroupgap": 0}, "margin": {"t": 60}, "dragmode": "select", "xaxis": {"matches": "y"}, "xaxis2": {"matches": "y2"}, "xaxis3": {"matches": "y3"}, "xaxis4": {"matches": "y4"}, "height": 900, "width": 750, "selections": [{"x0": 3, "x1": 4, "xref": "x2", "y0": 8, "y1": 6, "yref": "y"}, {"x0": 5, "x1": 1, "xref": "x3", "y0": 5, "y1": 4, "yref": "y"}]};
function clone(o) { return JSON.parse(JSON.stringify(o)); }
function cb(gd) { return JSON.stringify(gd.data[1].marker.colorbar || {}); }
function ax(gd) { return gd._fullLayout.xaxis ? Math.round(gd._fullLayout.xaxis._length) + 'px' : '?'; }
function dump(gd, el) {
  var cbs = gd.querySelectorAll('.colorbar');
  var w = cbs.length ? Math.round(cbs[cbs.length-1].getBoundingClientRect().width) + 'px' : 'none';
  el.textContent = 'trace1.marker.colorbar = ' + cb(gd) +
                   '\npanel width (xaxis._length) = ' + ax(gd) +
                   '\nrendered colorbar width = ' + w;
}

// Path A
var gdA = document.getElementById('A');
var dataA = clone(DATA);
dataA[1].marker.colorbar = { thicknessmode: 'pixels' };
Plotly.newPlot(gdA, dataA, clone(LAYOUT)).then(function () {
  dump(gdA, document.getElementById('mA'));
});

// Path B
var gdB = document.getElementById('B');
var dataB = clone(DATA);
dataB[1].marker.colorbar = {};
Plotly.newPlot(gdB, dataB, clone(LAYOUT)).then(function () {
  dump(gdB, document.getElementById('mB'));
  return Plotly.restyle(gdB, { 'marker.colorbar.thicknessmode': 'pixels' }, [1]);
}).then(function () {
  dump(gdB, document.getElementById('mB'));
});
</script>
</body>
</html>
Actual vs expected (measured with plotly 3.8.2, headless Chrome)
Path A (set at newPlot) Path B (set via restyle)
trace[1].marker.colorbar after render {"thicknessmode":"pixels"} {"thickness":16290,"thicknessmode":"pixels"}
panel width (_fullLayout.xaxis._length) 125 px 15 px
rendered colorbar width 71 px 16331 px

Expected: Path B behaves like Path A — thickness defaulted to ~30 px for pixels mode,
panels stay 125 px.

(Note: with random synthetic splom data the exact numbers differ — e.g. thickness:17250,
axis len ~15 — but the collapse reproduces identically.)

Analysis

colorbar.thickness is size-dependent when left at its default: in fraction mode the
default is ~30 / plotHeight (a small fraction), converted to pixels only at calc time.
When Plotly.restyle flips thicknessmode to pixels on a colorbar that still holds the
fraction-mode default, the default is apparently not re-coerced for the new mode — the
old tiny fraction survives, is interpreted as raw pixels on the next colorbar calc, and the
result (~16k px) is also written back into gd.data (user-visible trace), not just
_fullLayout.

Evidence that fits this reading:

  1. Restyling thickness together with thicknessmode
    ({'marker.colorbar.thickness': 20, 'marker.colorbar.thicknessmode': 'pixels'}) works
    fine — an explicit value bypasses the buggy default path.
  2. After Path B, the wrong value is observable on the user data object
    (gd.data[1].marker.colorbar.thickness === 16290), so a defaults-coercion result leaks
    back into gd.data.

First reported at plotly/plotly.py#5615;
the plotly.py maintainers asked for a pure-JS reproduction here.

Workaround

Include an explicit thickness in the same restyle call:

Plotly.restyle(gd, {
  'marker.colorbar.thicknessmode': 'pixels',
  'marker.colorbar.thickness': 20
}, [1]);

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par exécuter la reproduction fournie dans index.html avec Plotly.newPlot et Plotly.restyle, puis suivez la manière dont marker.colorbar.thicknessmode est géré pour les traces splom. La tâche est terminée lorsque l’application du mode via Plotly.restyle n’écrit plus thickness: 16290 et ne réduit plus les panneaux, tandis que le chemin newPlot reste correct.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
javascript
Domaine
data-visualization, frontend
Type d'issue
Bug
Difficulté
3/5
Temps estimé
1-2 jours
Activité
Active
Clarté
Plutôt claire
Accessibilité débutants
68/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.