Skip to content

violin trace: why an area is calculated if all values are 0? #3622

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
micosacak opened this issue Mar 11, 2019 · 8 comments · Fixed by #3626
Closed

violin trace: why an area is calculated if all values are 0? #3622

micosacak opened this issue Mar 11, 2019 · 8 comments · Fixed by #3626
Assignees
Labels
bug something broken

Comments

@micosacak
Copy link

Please see my question in stackoverflow

I have an array of values from 0-10 with and 20 groups in each. For some groups or categories all values are 0. When I use violin plot, there is an area calculated which is below 0, but I want to get thedifferent that I got from Seurat package VlnPlot. Is there a way to overcome that problem? Here is a part of java script code:

var my_violin = [];
var vln_layout = {};
var my_violin =[
{
    type:"violin",
    x:xvalues,
    y:my_categories,
    points:"all",
    pointpos:0,
    color:"black",
    width:0.75,
    marker:{color:"black",size:4},
    jitter:1,
    span:0,
    transforms:[
    {
        type:"groupby",
        groups:my_categories,
        styles:my_styles
    }
    ]
}
]

var vln_layout = {title: "my title",    xaxis:{showline: false,showgrid: false,zeroline: false,
    categoryorder: 'category ascending'}, yaxis: {showline: false,showgrid: false,zeroline:false},
    showlegend:true,legend:{traceorder:'normal',categoryorder:"ascending"}};

Plotly.newPlot('myDiv2', my_violin, vln_layout, {showSendToCloud: false});
@antoinerg
Copy link
Contributor

Thank you @micosacak for your interest in plotly.js and for reporting this.

When reporting an issue, it is more convenient for the maintainers if you provide a Codepen showing the problem. I prepared one here: https://codepen.io/antoinerg/pen/QoqWBb. Can you fork it and add the missing variables xvalues, my_categories and my_styles?

Thank you!

@micosacak
Copy link
Author

micosacak commented Mar 11, 2019

Thanks a lot @antoinerg. I forked the values as following;

xvalues and yvalues. my_categories is equal to xvalues. I changed it accordingly.

@micosacak
Copy link
Author

And especially, Cell_0, Cell_5, Cell_6, Cell_7 and Cell_17 have zero values for all. I also wonder why Cell_14 and Cell_16, as well with negative values.

@antoinerg
Copy link
Contributor

Trying to plot datasets [0,0,0,0] (left) and [0,0,0,1] (right) with violins:

Thanks @micosacak for reporting this issue!

@antoinerg antoinerg added the bug something broken label Mar 11, 2019
@antoinerg antoinerg changed the title plotly.js: why an area is calculated if all values are 0? violin trace: why an area is calculated if all values are 0? Mar 11, 2019
@antoinerg
Copy link
Contributor

Even when setting spanmode to hard, the calcSpan function returns [-1, 1] even if all values are zeroes. This happens when calling dummyAx.cleanRange(); on line 155:

function calcSpan(trace, cdi, valAxis, bandwidth) {
var spanmode = trace.spanmode;
var spanIn = trace.span || [];
var spanTight = [cdi.min, cdi.max];
var spanLoose = [cdi.min - 2 * bandwidth, cdi.max + 2 * bandwidth];
var spanOut;
function calcSpanItem(index) {
var s = spanIn[index];
var sc = valAxis.type === 'multicategory' ?
valAxis.r2c(s) :
valAxis.d2c(s, 0, trace[cdi.valLetter + 'calendar']);
return sc === BADNUM ? spanLoose[index] : sc;
}
if(spanmode === 'soft') {
spanOut = spanLoose;
} else if(spanmode === 'hard') {
spanOut = spanTight;
} else {
spanOut = [calcSpanItem(0), calcSpanItem(1)];
}
// to reuse the equal-range-item block
var dummyAx = {
type: 'linear',
range: spanOut
};
Axes.setConvert(dummyAx);
dummyAx.cleanRange();
return spanOut;
}

I haven't delved into violin much so I am not sure what is the best way to tackle the issue at hand. Any suggestions @plotly/plotly_js ?

@antoinerg
Copy link
Contributor

@alexcjohnson I'm tempted to return a tiny range around cdi.min and cdi.max when they're equal (say +/- 1E-6).

It looks fine alongside another violin:
newplot (8)
but when displayed alone, it has an arbitrary size:
newplot (9)

@alexcjohnson
Copy link
Collaborator

I don't think we can do that, whatever size we choose someone will come up with a data set that has a natural size smaller than that. It has to actually have zero size, even if that means a special case with its own drawing code.

@antoinerg
Copy link
Contributor

@alexcjohnson I don't know what I was thinking 😅! That would have been a horrible hack. PR #3625 is much better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug something broken
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants