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

adding-plotBuilder #345

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open

Conversation

bmatyasb
Copy link

No description provided.

@FBartos FBartos self-requested a review January 30, 2025 08:00
@FBartos
Copy link
Contributor

FBartos commented Jan 30, 2025

The PR above fixes the wrapper issues. You should be able to load the module and get the main analysis function running.
(you now get errors about undefined '%>%' command)

@FBartos
Copy link
Contributor

FBartos commented Jan 30, 2025

The code is nicely formated and quite readable, I think it's pretty much compliant with the JASP style. Very nice! There are two issue I will need you to help us with (which is also what Don mentioned in the Mattermost channel). That's:

  1. not importing the complete package namespaces, i.e., your original NAMESPACE file had,
import(jaspBase)
import(jaspGraphs)
import(ggplot2)
import(tidyplots)
import(rlang)
import(dplyr)
import(tidyr)
import(ggprism)
import(patchwork)
import(tidyverse)
import(ggpubr)
import(ggeasy)
import(forcats)

but this easily messes the internal JASP namespace. Instead, it's highly preferred to use e.g.,
ggplot2::ggplot() + ggplot2::theme_void() notation

  1. trimming down on some of the large package dependencies wherever possible. The main issues are
  • tidyverse
  • tidyplots
  • tidyr
  • dplyr
    (am I missing some @vandenman ?). We cannot really ship those packages because a) they have an extremely large dependency base and the potential of breaking JASP during the update is too big, and b) they are most wrappers meant for analysis scripts but not for package development - they are not very stable and they might change (which would brick the analysis). Maybe Don has a more precise explanation on this.

This will, unfortunately, require some rewriting of the code, but pretty much tidyverse convenience functions have baseR alternatives. I don't really use tidyverse at all so it's a bit challenging to me figure out what are all the imported functions (apart from the pipe signs haha), but I would guess that using ChatGPT like tool could make this not too difficult. Does this seem reasonable to you and that it would be manageable for you to implement?

@FBartos FBartos requested a review from vandenman January 30, 2025 08:29
@bmatyasb
Copy link
Author

bmatyasb commented Jan 30, 2025 via email

@FBartos
Copy link
Contributor

FBartos commented Jan 30, 2025

tidyr and dplyr are both imported by tidyplots (so removing them while keeping tidyplots won't help that much). I think tidyverse has to go for sure, but @vandenman will have the final say for the rest

@EJWagenmakers
Copy link

As an aside, I have asked @PabRod to stress this point in the documentation. If we make a list of things that contributors ought to be aware of, this one might break into the top 3....

@bmatyasb
Copy link
Author

bmatyasb commented Jan 30, 2025 via email

@EJWagenmakers
Copy link

EJWagenmakers commented Jan 30, 2025

Also, will this still be as relevant when we have our online module library in llace? I know this will take a while to get done, but still useful to know [correction: we want this in Des riptives, so part of the JASP core functionality]

@vandenman
Copy link
Contributor

Going by the list here I would suggest

package keep
ggplot2 👍
tidyplots 👍
rlang 👍
dplyr 👍
tidyr 👍
forcats 👍
patchwork 👍
ggprism
tidyverse
ggeasy
ggpubr

ggpubr is a bit of a questionable case, because since both jaspGraphs and tidyplots use it it is reeled in anyway. But in general, try to keep the dependencies as lean as possible. So don't use tidyverse directly but figure out what subpackage you need from it. Likewise, we prefer not to reel in things like ggeasy and instead do the theming manually. Regarding ggprism, it's tricky to figure out where you use it at the moment (due to import instead of importFrom in the namespace) but if it's about the color schemes then we typically add these in jaspGraphs.

A good rule of thumb with dependencies (that we sadly aren't very strict about) is that everything in github.com/tidyverse and github.com/r-lib is fine to use, and the rest we look at on a case-by-case basis.

@vandenman
Copy link
Contributor

also, you need to adjust the DESCRIPTION file otherwise the unit tests will surely fail to install the package.

@bmatyasb
Copy link
Author

bmatyasb commented Jan 30, 2025 via email

@vandenman
Copy link
Contributor

what about ggpubr::geom_bracket? that looks quite similar to ggprism::add_pvalue.

@bmatyasb
Copy link
Author

bmatyasb commented Jan 30, 2025 via email

@bmatyasb
Copy link
Author

bmatyasb commented Jan 30, 2025 via email

@bmatyasb
Copy link
Author

bmatyasb commented Jan 30, 2025 via email

@bmatyasb
Copy link
Author

bmatyasb commented Jan 30, 2025 via email

@FBartos
Copy link
Contributor

FBartos commented Jan 31, 2025

I think library(package) should never be done because it loads the whole package namespace into the current package (which can create a lot of mess).

When JASP loads a module, it loads the namespace of all its analyses (in the same way as if you develop an R package). It is very easy to get namespace conflicts among analyses within the same module. Therefore, the package::function format is almost always preferred as it ascertains that the correct function is called (even when multiple packages export the same function) and the overall module namespace remains concise.

@vandenman
Copy link
Contributor

Am I allowed to use import() or importFrom(), or library() inside the
script, or should I use the package::function format?

never library, import is fine for e.g., jaspBase. importFrom I'd use if you use have a function from a package that you use often. pkg::function I'd use in most other cases.

@bmatyasb
Copy link
Author

bmatyasb commented Feb 3, 2025 via email

@bmatyasb
Copy link
Author

bmatyasb commented Feb 3, 2025

Sorry, the addition of the #2 tag was completely accidental

Copy link
Contributor

@vandenman vandenman left a comment

Choose a reason for hiding this comment

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

Just went over the QML, see the comments below. Overall this looks really good and complete, thanks!

Form {
columns: 1

infoBottom:
Copy link
Contributor

Choose a reason for hiding this comment

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

Two things.

  1. This looks generated. If it is, can you add the R code to generate this as a comment above this for future updates?
  2. You can do string continuation with \ (see https://forum.qt.io/topic/113667/multiline-strings/2). Not sure how to handle \n though.

/// Here begins the main plot control
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

TabView {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you please indent this with tabs instead of spaces? :)

Comment on lines 2360 to 2372
DropDown {
name: "sortYLabelsOrder"
label: "Sort Y labels"
values: ["Increasing", "Decreasing"]
startValue: "Increasing"
}

DropDown {
name: "aggregationFunY"
label: "By"
values: ["mean", "median"]
startValue: "mean"
}
Copy link
Contributor

Choose a reason for hiding this comment

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

qsTr for the labels and see other comment about values and startvalues.

Comment on lines 2554 to 2573
DoubleField {
name: "topMargin"
label: "Top"
value: 10
}
DoubleField {
name: "bottomMargin"
label: "Bottom"
value: 10
}
DoubleField {
name: "leftMargin"
label: "Left"
value: 10
}
DoubleField {
name: "rightMargin"
label: "Right"
value: 10
}
Copy link
Contributor

Choose a reason for hiding this comment

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

labels need qsTr.

Comment on lines 2494 to 2519
{ label: "Default: JASP colors", value: "colors_JASP" },
{ label: "Discrete: Friendly", value: "colors_discrete_friendly" },
{ label: "Discrete: Seaside", value: "colors_discrete_seaside" },
{ label: "Discrete: Apple", value: "colors_discrete_apple" },
{ label: "Discrete: Friendly Long", value: "colors_discrete_friendly_long" },
{ label: "Discrete: Okabe Ito", value: "colors_discrete_okabeito" },
{ label: "Discrete: IBM", value: "colors_discrete_ibm" },
{ label: "Discrete: Metro", value: "colors_discrete_metro" },
{ label: "Discrete: Candy", value: "colors_discrete_candy" },
{ label: "Discrete: Alger", value: "colors_discrete_alger" },
{ label: "Discrete: Rainbow", value: "colors_discrete_rainbow" },
{ label: "Continuous: Viridis", value: "colors_continuous_viridis" },
{ label: "Continuous: Magma", value: "colors_continuous_magma" },
{ label: "Continuous: Inferno", value: "colors_continuous_inferno" },
{ label: "Continuous: Plasma", value: "colors_continuous_plasma" },
{ label: "Continuous: Cividis", value: "colors_continuous_cividis" },
{ label: "Continuous: Rocket", value: "colors_continuous_rocket" },
{ label: "Continuous: Mako", value: "colors_continuous_mako" },
{ label: "Continuous: Turbo", value: "colors_continuous_turbo" },
{ label: "Continuous: Blue Pink Yellow", value: "colors_continuous_bluepinkyellow" },
{ label: "Diverging: Blue to Red", value: "colors_diverging_blue2red" },
{ label: "Diverging: Blue to Brown", value: "colors_diverging_blue2brown" },
{ label: "Diverging: BuRd", value: "colors_diverging_BuRd" },
{ label: "Diverging: BuYlRd", value: "colors_diverging_BuYlRd" },
{ label: "Diverging: Spectral", value: "colors_diverging_spectral" },
{ label: "Diverging: Icefire", value: "colors_diverging_icefire" }
Copy link
Contributor

Choose a reason for hiding this comment

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

labels need qsTr

updatedPlots <- plotResults$updatedPlots

if (!is(jaspResults[["plotGridContainer"]], "JaspContainer")) {
plotGridContainer <- createJaspContainer(title = "Plot Grid")
Copy link
Contributor

Choose a reason for hiding this comment

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

    plotGridContainer <- createJaspContainer(title = gettext("Plot Grid"))

we should mark this titles text by gettext/gettextf to make it translatable.

Comment on lines 48 to 62
name: "PlotBuilderTab"

rowComponent: Group {

childControlsArea.anchors.leftMargin: jaspTheme.contentMargin

Group{
columns:2
TextField {
name: "plotId"
label: qsTr("Plot ID")
fieldWidth: 200
placeholderText: qsTr("Enter Plot ID")
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
name: "PlotBuilderTab"
rowComponent: Group {
childControlsArea.anchors.leftMargin: jaspTheme.contentMargin
Group{
columns:2
TextField {
name: "plotId"
label: qsTr("Plot ID")
fieldWidth: 200
placeholderText: qsTr("Enter Plot ID")
}
name: "PlotBuilderTab"
newItemName: qsTr("Plot 1")
rowComponent: Group {
childControlsArea.anchors.leftMargin: jaspTheme.contentMargin
Group{
columns:2

Adding the newItemName automatically names the tabs "Plot 1", "Plot 2", ...
image
(and users can rename them by double clicking them)

These can be also used as the plotId - a bit of an annoying issue now is that you need to fill in the idea first, otherwise the whole analysis is terminated with an error. Using the tab names circumvents the issue (in case you names without spaces and special symbols, it should be easy to replace them with underscores using gsub etc?)

This needs to be propagated into the R-code. While now the code takes the plotId from options[["PlotBuilderTab"]][[1]][["plotId"]], now it should refer to the name in options[["PlotBuilderTab"]][[1]][["value"]]
(I did not do that as it's a too big change for a suggested change here)

Copy link
Author

Choose a reason for hiding this comment

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

that's a great idea! thanks a lot! just a couple of lines to rewrite and it works.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks :) I will do a deeper dive and more suggestions once all the previous parts are addressed (it's a bit of a mess with al the qml suggestions right now) Could you maybe just prompt me to do so on mattermost?

and some commented script
- add p values: color, size and start of p values on y axis should be set universally, I fixed this (also in qml)
- annotation line: the line is only created if all four required parameters are given, so it does not result in an error
- padding: i added padding between axis and axis ticks, so that if you manually set the x/y axis minimum to 0, the value should be at the bottom of the axis
@FBartos
Copy link
Contributor

FBartos commented Mar 4, 2025

Hi @bmatyasb , sorry for the delay with the review, I started teaching this month and preparation it is taking much more time than expected. I now went over the functionality of the non-repeated measurements options and I found couple of bugs that I would ask you to adress (+ some small suggestions). I tried looking into the repeated measurements options as well, but a) it immediatelly produces an error once switched to b) the qml menu seems to be collapsed at the variable selection. Could you please update it first? (I assume most of the issue will be the same across the repeated / non-repeated measures settings).

Some additional code suggestions will follow in a separate comment and suggestions.

  • The Sum value checkbox does not work
    no-sum-value.zip
    (unzip)
    Issue: the sum value is not displayed
    Issue2: Mean value / Median value options do not work. (seems like a consistent problem when adding values to the figure across several options)

  • The Proportions section does not work when both X-axis and Y-axis variable are specified
    x-and-y-proportions-error.zip
    (unzip)
    Issue: the plot crashes with error
    Fix: Probably the best approach would be to also disable the checkbox if both x & y variables are specified, e.g., variableXPlotBuilder.count > 0 && variableYPlotBuilder.count > 0 or to display a more informative error message on the plot output
    Issue2: Similarly, Mean / Median section require both variables, but the checkboxes are enabled while only one variable is supplied. As such, they crash the plot with uninformative message when selected. I think this is an error in some later options as well. Could you please check that the options are disabled if improper input is specified? The JASP filosophy is user is guided into options that are sensible given the input as we minimalize the input error on the side of GUI design whenever possible. It makes for a good user experience (and less GitHub bug reports :).

  • The Area stack in Proportions section does not work with correct input variables
    x-and-y-proportions-error-2.zip
    (unzip)
    Issue: "Dicreate values supplied to continuous scale error"

  • The Reference / annotation line in the Curve fit ... section
    image
    Issue: the input field is a bit too long
    Issue2: Should we consider adding a default 0/0 values? I'm not sure, maybe not because it will be quite off for many scenarios and users will need to change it?

  • Title does not work for Split by ... plots.

  • Adjust legend specifying new color labels makes the plot crash both the original and new levels are specified. Could you add a check that skips the given row untill both values are different from ""

  • P-value brackets I tried adding them to a barplot by the default settings places them outside of the plotting range
    image
    I tried moving them downwards using the Position on the Y... but it does not really work as it decreases the y-axis range till it is too small to fit (and then its displayed)
    I tried also manually setting the y-axis range, but it gets overriden. I'm not really sure how to use this option.
    Issue 2: the default text for the p-value is or 0.49, maybe we could change it to p < 0.05 or something more suitable?

  • The plot layout options will require a bit more help. I created two figure and wanted them to be at this position:
    Plot 1
    Plot 2
    rather than
    Plot 1 | Plot 2
    but I did not figure out how to do so

Other suggestions

  • in Proportions, the Bar stack and Area stack options have (absolute) and (relative) versions. Do you think there is any application when user would like to display both of them simultanously? If so, the figure probably should have a secondary axis that shows scaling for the other option. I think that it probably not the case -> the two version of options could be consolidated into a single option with a radio button switching between relative / absolute values version. Maybe even better would have a switch between relative/absolute values output for the whole Proportions section (so it applies to both the Bar and Area stacks).

@FBartos FBartos self-requested a review March 4, 2025 10:30
Copy link
Contributor

@FBartos FBartos left a comment

Choose a reason for hiding this comment

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

These are mostly capitalization naming changes. I'm not sure I caught all, could you please propagate through if I missed any based on the same logic?

Comment on lines +181 to +186
onCountChanged: {
if (count > 0) {
colorByVariableX.checked = false;
colorByVariableY.checked = false;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with @bmatyasb that automatically unselecting the options whenever the variables change etc is very handy. There is a lot of nested menus and unclicking all of them becomes unfeasible and very easy to lose track at

}
}
}
Group {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do I understand correctly that coloring can be done by either the variable assigned to the Group/Color by variable input or by the X or Y variable? Maybe changing the variable name to Group Variable and adding a radio button group below the input that changes the color mapping between X Axis Variable / Y Axis Variable / Group Variable with radio buttons enabled only if the corresponding variable is specified would make this clearer?

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe even better, this switch could be in the Plot style section, with the default corresponding to the Group Variable

@bmatyasb
Copy link
Author

bmatyasb commented Mar 4, 2025 via email

@FBartos
Copy link
Contributor

FBartos commented Mar 5, 2025

Oh, I see now how to use it, yes, I got it working and also created some figures.
If I understand correctly,
image
these work only as x-axis and y-axis titles, right? If so, aren't they duplicitous to the Adjust y-axis and Adjust x-axis tabs? I checked and adding a title there overrides the original title. I'm assuming you let user specify them, because you need to have some defaults (for names in the data.frame as well). This, however, creates a bit of friction as an error is shown till any names are specified.

I would suggest removing both text fields and setting the default names to "Repeated measures" and "Values". Users can then directly modify them in the Adjust y-axis and Adjust x-axis sections. Would that make sense?

bmatyasb and others added 10 commits March 5, 2025 09:33
Co-authored-by: František Bartoš <[email protected]>
Co-authored-by: František Bartoš <[email protected]>
Co-authored-by: František Bartoš <[email protected]>
Co-authored-by: František Bartoš <[email protected]>
Co-authored-by: František Bartoš <[email protected]>
Co-authored-by: František Bartoš <[email protected]>
Co-authored-by: František Bartoš <[email protected]>
Co-authored-by: František Bartoš <[email protected]>
Co-authored-by: František Bartoš <[email protected]>
Co-authored-by: František Bartoš <[email protected]>
@bmatyasb
Copy link
Author

bmatyasb commented Mar 5, 2025

  • You wrote that mean, sum and median value do not work. I figured out that they don't because there is an ordinal variable on the x-axis. For some reason, if the variable is defined as an ordinal variable in JASP, value doesn't work. I haven't dug deep into how to solve this yet, just thought I'd let you know.

  • The p value problem does not occur for me if I set the p coefficient on the Y axis to a value that is within the range. Otherwise, I would recommend that the user increase the range setting of the Axes. Would you recommend a more obvious, more "automatic" solution here?

image

  • Yes, the plot layout is a bit tricky. A row is a column, and if you want to insert plots underneath each other in a column, you simply have to write the IDs of the plots one after the other. That way you get different rows in the same column.
    image

-The proportion only works if there is an X variable (or Y) and a colour variable. So you can't have X and Y the same. It was conditioned that way in a previous version, so you could only make a Prop plot if X OR Y and color variable were specified, I just accidentally rewrote that.

I am currently working on fixing everything else.

@FBartos
Copy link
Contributor

FBartos commented Mar 5, 2025

Oh, I understand how the layout is supposed to work now. Then, I would suggest renaming the Plot to Column 1
image
and clicking the + element adds Column 2. That would be a bit more intuitive

@bmatyasb
Copy link
Author

bmatyasb commented Mar 5, 2025

unfortunately I can't figure out why the value values only work if the variable is set to nominal and not ordinal in JASP... :/ or how can I solve this :/..

@bmatyasb
Copy link
Author

bmatyasb commented Mar 5, 2025

sorry, I have the solution.

@bmatyasb
Copy link
Author

bmatyasb commented Mar 7, 2025

@FBartos Can you help me to display the titles Column 1, Column 2 etc in the plot layout? Can you help me to display the titles Column 1, Column 2 etc in the plot layout? You wrote that Plots should be rewritten to Column, with a number after the Column indicating which component list the user is at. I just can't quite get this to solve the problem.

ComponentsList {
                id: rowSpecifications
                name: "rowSpecifications"
                title: qsTr("Specify layout")
                addItemManually: true

                rowComponent: Row {
                    Group {
                        title: qsTr("Plots")

                        TextField {
                            name: "plotIDs"
                            label: qsTr("Plot IDs")
                            placeholderText: qsTr("PlotID1, PlotID2")
                            fieldWidth: 120
                        }

                        TextField {
                            name: "rowHeightsColumn"
                            label: qsTr("Plot heights")
                            placeholderText: qsTr("1,1")
                            fieldWidth: 120
                        }
                    }

                    Group {
                        title: qsTr("Labels and legend")

                        TextField {
                            name: "labelsColumn"
                            label: qsTr("Labels")
                            placeholderText: qsTr("A, B, C, etc...")
                            fieldWidth: 90
                        }

                        CheckBox {
                            name: "getCommonLegendColumn"
                            label: qsTr("Collect legend")
                        }
                    }
                }
            }

@FBartos
Copy link
Contributor

FBartos commented Mar 7, 2025

Just added the suggested change -- I found out that I did something similar in a different module and it worked out of the box

bmatyasb and others added 5 commits March 7, 2025 14:33
Co-authored-by: František Bartoš <[email protected]>
Co-authored-by: František Bartoš <[email protected]>
SE control for curve fit
conditions for error bars
@bmatyasb
Copy link
Author

bmatyasb commented Mar 7, 2025

I pushed the following changes:

  • fixed the mean and median to work when both x and y variables are specified (this works in tidyplot)
  • proportion only works if x OR y and color are given. relative and absolute proportions are toggled with radio buttons...
  • i fixed the problem with the plot layout. plus i noticed that the "row based" layout doesn't work if there is no "column based" layout, so i fixed that too.
  • also the error-bart was badly conditioned. it is now selectable if there is x and y variable.
  • regression line can be fitted even if otherwise colored by x or y variable
  • moved the coloring options to plot style and added None, grouping variable, x, y and repeats measures as options
  • the plot title now works even if there is a facet. i also specified the name of the variable used to create the facet as the title, and the two overwrote each other. But now the facet name has been moved to subtitle.

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.

5 participants