[BUG]: Violin plot width incorrectly calculated in grouped mode with multiple x-categories
Personne n'a encore pris cette issue.
- Langage dominant
- JavaScript
- Étoiles
- 18.3k
- Forks
- 2k
- Merge moyen
- 2 j 12 h
- PR mergées (30 j)
- 28
Description
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
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:
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.
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par lire src/traces/box/cross_trace_calc.js et reproduisez l’exemple avec six traces de violon, le mode groupé et sans offsetgroup. Comparez l’allocation de la largeur à chaque position x avec le calcul actuel des traces globales, puis vérifiez que l’espacement des traces de violon groupées correspond aux paramètres sans intervalle et déterminez si la logique partagée des box-plots est affectée.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- javascript
- Domaine
- data-visualization
- Type d'issue
- Bug
- Difficulté
- 3/5
- Temps estimé
- 1-2 jours
- Activité
- À l'abandon
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 58/100