plotly / plotly/plotly.js

[BUG]: Violin plot width incorrectly calculated in grouped mode with multiple x-categories

Aperta
#7,611 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

bug
Lingua principale
JavaScript
Stelle
18.3k
Fork
2k
Merge medio
2g 12h
PR unite (30g)
28

Descrizione

Description

When using violinmode: 'group' with violins at multiple x-axis categories, but without offsetgroup set, the width calculation uses the total number of traces across the entire plot instead of the number of traces at each x-position. This causes excessive empty space even when gap parameters are set to 0.

Screenshots/Video
Image
Steps to reproduce
<!DOCTYPE html>
<html>
<head>
	<!-- Load plotly.js into the DOM -->
	<script src='https://cdn.plot.ly/plotly-3.1.2.js'></script>
</head>
<body>
    <div id="myDiv"></div>
    <script>
        // Create data: 2 models × 3 evaluations = 6 traces total
        // But at each x-position, there are only 2 violins

        const models = ["Model A", "Model B"];
        const evals = ["Eval 1", "Eval 2", "Eval 3"];
        const colors = ["blue", "red"];

        const traces = [];

        models.forEach((model, modelIdx) => {
            evals.forEach((evalName, evalIdx) => {
                const yData = Array.from({length: 50}, () =>
                    Math.random() * 2 - 1 + modelIdx
                );

                traces.push({
                    type: 'violin',
                    x: Array(50).fill(evalName),
                    y: yData,
                    name: model,
                    legendgroup: model,
                    scalegroup: model,
                    // offsetgroup: model, // Uncomment to fix spacing
                    showlegend: evalIdx === 0,
                    line: { color: colors[modelIdx] }
                });
            });
        });

        const layout = {
            violinmode: 'group',
            violingap: 0,      // No gap between categories
            violingroupgap: 0, // No gap between groups
            title: 'Bug Demo: Excessive empty space despite gap=0'
        };

        Plotly.newPlot('myDiv', traces, layout);
    </script>
</body>
</html>
Notes
Root Cause

I think the issue is in src/traces/box/cross_trace_calc.js.

When traces are split across multiple x-categories (each trace appears at only one x-value) but offsetgroup is not set, the formula incorrectly uses the global trace count numTotal:

var num = nOffsetGroups || numTotal;
...
bdPos = dPos * groupFraction * groupGapFraction / num;

This should divide by the number of traces at each specific x-position, not the total number of traces in the plot.

Workaround

Uncommenting offsetgroup: model, below scalegroup: model, in the above code produces the expected behaviour with no space between violins. See the below image:
Image
However I don't believe this should be required - certainly it isn't mentioned in the docs.

Related

This probably also affects box plots since they share the width calculation logic in cross_trace_calc.js.

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia leggendo src/traces/box/cross_trace_calc.js e riproduci l’esempio con sei tracce violin, la modalità raggruppata e senza offsetgroup. Confronta l’allocazione della larghezza in ogni posizione x con l’attuale calcolo globale delle tracce, quindi verifica che la spaziatura delle tracce violin raggruppate corrisponda alle impostazioni a intervallo zero e valuta se la logica condivisa dei box-plot è interessata.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
javascript
Ambito
data-visualization
Tipo di issue
Bug
Difficoltà
3/5
Tempo stimato
1-2 giorni
Stato di attività
Ferma
Chiarezza
Specificata chiaramente
Idoneità per principianti
58/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.