ImmuneDynamics / Spectre

A computational toolkit in R for the integration, exploration, and analysis of high-dimensional single-cell cytometry and imaging data.
https://immunedynamics.github.io/spectre/
MIT License
56 stars 21 forks source link

Problem with make.multi.plot.R #180

Closed markmelzer closed 8 months ago

markmelzer commented 9 months ago

Hi ImmuneDynamics Team,

I am using your package for the analysis of some flow cytometry data and run into a problem when executing the make.multi.plot function as described in your tutorial (Discovery workflow with batch alignment using CytoNorm). Whenever I want to create a multi plot I get the error: Error in unit(rep(1, ncol), "null") : 'x' and 'units' must have length > 0 With the traceback: 5: stop("'x' and 'units' must have length > 0") 4: unit(rep(1, ncol), "null") 3: arrangeGrob(...) 2: gridExtra::grid.arrange(grobs = plots, ncol = num.cols, nrow = num.rows) 1: make.multi.plot(cytnrm.sub, "UMAP_X", "UMAP_Y", cellular.cols)

I tried to recreate the error by viewing the source and running the internal code step by step. On my machine (macOS Ventura 13, R version 4.3) the problem is that the output of the make.colour.plot function is NULL and therefore nothing is appended to the list called 'plots'. This results in the shown error, when grid.arrange is called. For now I was able to work around that problem by plotting with make.colour.plot and using grid.grab() to save the plot to the list. However, that is not very elegant since every plot is plotted first.

Thus, any question is: Is this a general problem with the function or is it a problem with my data? The input data is a data.table with 10000 observation and 20 variables (incl. meta data and the two UMAP dims) from fas files, as it is created in the tutorial.

I appreciate your help. Best wishes, Mark

tomashhurst commented 9 months ago

Hi @markmelzer , thanks for reaching out! This sometimes comes up if the arguments are used the wrong way around. For example, there are two arguments -- one for how to divide up the plots, and one for what the colour axis is on each. For example, one might want to split the plots by the experiment group or batch, and then colour by a marker. If you accidentally split by the marker, in theory, the function wants to make a separate plot based on each value of that marker, which throws it. Try checking the plot.by and divide.by arguments to see if they are set up correctly?

markmelzer commented 9 months ago

Hi @tomashhurst, Thanks for your answer. I checked various arguments, but could not resolve the issue. What I want to achieve are several UMAP plots, each coloured by the expression of a different marker. For this, I have a data table 'dat', where 2 columns are "UMAP_X" and "UMAP_Y", 13 numerical columns 'cellular.cols' with marker expressions, and a few descriptive columns. Thus, I call the multi plot with: make.multi.plot(dat, "UMAP_X", "UMAP_Y", cellular.cols) This results in the error above, which I don't quite understand. If I use the same parameters for make.colour.plot and choose one of the cellular.cols there are no problems. In case this might be important: I am using the version of the development branch. Sorry for the troubles, Mark

tomashhurst commented 8 months ago

@markmelzer hmm weird. make.multi.plot should be OK in dev branch. Try running str(dat) -- it is possible that one of the cellular marker columns is stored as character or something weird, check and see.

tomashhurst commented 8 months ago

@markmelzer by amazing coincidence I just had the exact same error when repeating a previous analysis of mine on a new dataset. I will investigate and share the fix, see if it works for you.

tomashhurst commented 8 months ago

@markmelzer OK inside make.multi.plot we use make.colour.plot to make the individual plots, store those in a list, and then tile them together using grid.arrange from the gridExtra package. The individual colour plots are being created (and in my workflow they get generated and saved on disk as per usual), but not stored in the list as they are supposed to -- as a result, there is nothing to tile together at the end of the function. We will sort out a fix and let you know.

tomashhurst commented 8 months ago

OK fixed. Just restored this line. We have made an update in the development branch, but it was unchanged in the master branch (i.e. it was working as per usual in master). Re-install from dev (or master) and you should be sorted.

markmelzer commented 8 months ago

@tomashhurst Fantastic, thank you! Looks way better now🤩 You might have noticed, but as a consequence to the fix, it also prints the grid table when you call make.colour.plot now. Just a minor issue, but I think it can be quickly solved by an if-statement around the return statement, which is only run when calling the plot from the make.multi.plot function.