Skip to content
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

Volcano #19

Merged
merged 40 commits into from
Apr 17, 2023
Merged

Volcano #19

merged 40 commits into from
Apr 17, 2023

Conversation

asizemore
Copy link
Member

@asizemore asizemore commented Mar 27, 2023

Resolves VEuPathDB/web-components#463

Required for first delivery of mbio differential abundance app. More details on the plot here

This PR adds a volcano plot component using visx. It does not attempt to add everything necessary for the "fully functional" volcano plot that lives in the EDA, but gives the backbones for us to build upon in the future.

To Dos left for later work

Other notes:

  • my approach for changing the opacity is pretty lame right now. I couldn't figure out how to pass opacity to the glyph series. It must be possible...

@asizemore
Copy link
Member Author

One question - i'm starting to change my mind about who does the color choices. Maybe plot.data only sends back data and the component breaks up into colors. Seems like this volcano component could be a little smarter and not rely so much on everyone else...

@asizemore
Copy link
Member Author

All up and running now! Ready for review!

@asizemore asizemore marked this pull request as ready for review April 7, 2023 14:36
import { NumberRange } from '../types/general';
import {
XYChart,
Tooltip,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: 'Tooltip' is declared but its value is never read.

// Determine mins, maxes of axes in the plot.
// These are different than the data mins/maxes because
// of the log transform and the little bit of padding.
//
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Dangling // 👯

Comment on lines 178 to 179
// From docs " For correct tooltip positioning, it is important to wrap your
// component in an element (e.g., div) with relative positioning."
Copy link
Contributor

@adnauseum adnauseum Apr 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

random: If you or anyone would like to understand absolute/relative positioning, this Codepen might help.

The docs say this because it sounds like the tooltips are positioned absolutely. Absolutely positioned elements position themselves in relation to their nearest parent that's positioned relatively. 🤯

You likely know this, but I just wanted to put it in there in case!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i did not know this! Thank you! That was a really clear example

yValue: number, // the raw pvalue
significanceThreshold: number,
log2FoldChangeThreshold: number,
significanceColors: string[] // Assuming the order is [high, low, not significant]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: This isn't at all unclear code or anything complicated, so this is really just a suggestion. I don't know if it makes the code better. Given this assumption, you could name the indicies:

const HIGH = 0;
const LOW = 1;
const INSIGNIFICANT = 2;

 if (yValue >= significanceThreshold) {
    return significanceColors[INSIGNIFICANT];
  }

 if (xValue >= log2FoldChangeThreshold) {
    return significanceColors[HIGH];
  }
...

if (dataXMin && dataXMax) {
xMin = Math.log2(dataXMin);
xMax = Math.log2(dataXMax);
xMin = xMin - (xMax - xMin) * 0.05;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit/suggestion: 0.05 is the measure of statistical significance, right? Maybe we can save that to a constant called STATISTICAL_SIGNIFICANCE_THRESHOLD?

@asizemore
Copy link
Member Author

@dmfalke and @adnauseum ready for your review again!

I didn't end up making the find-min-and-max part into a function since we were sort of back and forth about it and it's a little unique to volcano. If you feel strongly about it though i'm happy to do it!

One new change - we learned that we don't expect to ever need the raw fold change values, so we're just going to have the backend return log2(fold change) so that the frontend doesn't have to do it.

I'll turn to working on the confluence doc for a bit while it's all fresh in my mind.

Copy link
Contributor

@adnauseum adnauseum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 🌋 🙌

LGTM!!!

Copy link
Member

@dmfalke dmfalke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This all looks great! Just one question about the babel plugin.

plugins: ['@babel/plugin-proposal-nullish-coalescing-operator'],
plugins: [
'@babel/plugin-proposal-nullish-coalescing-operator',
'@babel/plugin-syntax-class-properties',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this added? I don't see class properties used anywhere.

Copy link
Contributor

@adnauseum adnauseum Apr 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!! I forgot to ask about this in our PR review! I was curious since it's scoped to storybook.

Ann's probably hacking us 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh yes good catch! This was a byproduct of my adventures trying to install some of the visx packages a while back. I just removed it and all seems to work 👍

@@ -283,6 +283,9 @@ export const gradientConvergingColorscaleMap = scaleLinear<string>()
.range(ConvergingGradientColorscale)
.interpolate(interpolateLab);

// Significance colors
export const significanceColors = ['#AC3B4E', '#0E8FAB', '#B5B8B4'];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only thing I saw that made me a bit uncomfortable.. say some instances of volcano plot want to use two colors rather than three, and not distinguish high vs low?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I swapped the order around so it goes 'not significant, high, low". That way when we do have a use case for two colors only, the component can get a prop that says use 2 or 3 colors, and it'll just use the first two or first three colors from the list. If for some reason we wanted four colors later, we could just add onto this array.
This is assuming that we're happy with the colors being repeated in this way. Worth a discussion when that comes around i'd imagine.

I also am not considering these choices of colors final. I think they should go through data viz first. I'll make a new issue to be sure it doesn't get lost!

@asizemore
Copy link
Member Author

Thanks everyone for the feedback!!

@asizemore asizemore merged commit 3f90637 into main Apr 17, 2023
@asizemore asizemore deleted the volcano branch April 17, 2023 11:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

add volcano component
4 participants