Page 1 of 1

How to show a dynamic number of ggplot2 objects ...

Posted: Mon Feb 10, 2025 12:47 pm
by jojop2
I have a grouping variable.
For each single value a list of plots is given back, which I need to show in the result pane.

With a specific title and description for each plot.

How is that working?

Re: How to show a dynamic number of ggplot2 objects ...

Posted: Tue Feb 11, 2025 1:35 am
by jonathon
do you know the number of plots there will be "in advance" or is it hard to predict and depends on what the analysis finds?

jonathon

Re: How to show a dynamic number of ggplot2 objects ...

Posted: Tue Feb 11, 2025 5:14 am
by jojop2
I can calculate the number of plots in advance, based on the unique values in the group column of the dataset.

I forgot to mention, that my existing function returns the plots in a list. So the plots cannot be build up from scratch in jamovi.

Thank you!
Joe

Re: How to show a dynamic number of ggplot2 objects ...

Posted: Tue Feb 11, 2025 5:32 am
by jonathon
i think you want something like this in your .r.yaml :

Code: Select all

    - name: plots
      title: Plots
      type: Array
      description: an array of plots
      items: (levels(vars))    #  substitute in the name of your Variable option into "vars"
      template:
          title: $key
          type: Image
          description: descriptives plot
          width: 350
          height: 300
          renderFun: .plot
jonathon

Re: How to show a dynamic number of ggplot2 objects ...

Posted: Tue Feb 11, 2025 6:05 am
by jojop2
Thank you for the immediate reply.

Is it possible to define, that if the vars is not filled, only one plot is built and otherwise the "levels(vars)"?

Is it correct, that I don't need the .run function, only the .plot function, if I only want to show plots?

How I understand it now, I would write sth like this in the .plot function:
list_of_plots <- externalFunctionCreatingPlots(self$data, self$options$measure, self$options$groups)

Do I have to iterate over the plot list to print each?

Joe

Re: How to show a dynamic number of ggplot2 objects ...

Posted: Tue Feb 11, 2025 6:59 am
by jonathon
> Is it possible to define, that if the vars is not filled, only one plot is built and otherwise the "levels(vars)"?

if you're wanting that, then you'll need to pursue a different approach ... leave the items property undefined, define a method called .init() alongside .run() ... and call

self$results$nameOfPlotArrayObject$addItem(key=nameOfPlot)

as many times as you'd like plots.

> Is it correct, that I don't need the .run function, only the .plot function, if I only want to show plots?

we generally try and minimise what runs inside a plot function, and try to do most of the processing inside of the .run function. ideally, the run function calculates the minimal geometry for a plot, than minimal geometry gets stored in the plots state, and then the plot function does the absolute minimum mapping the geometry to the plot device.

if the user wants to export the plot, no problem, we load the state, and create the plot in the target format ... without having to do any additional computation.

of course, in practice, many R packages make this difficult if not impossible ... and so such a neat separation between "computation" and "presentation" isn't always possible. we sometimes end up performing the *whole* analysis again, just because the user requested to export a different format.

> list_of_plots <- externalFunctionCreatingPlots(self$data, self$options$measure, self$options$groups)

if you're using self$data inside your plotting code, then you'll need to add

requiresData: true

to the plot object in the .r.yaml ...

and then you'll want something like

.plot = function(image, ...) {
list_of_plots <- externalFunctionCreatingPlots(self$data, self$options$measure, self$options$groups)
plot <- list_of_plots[[image$key]]
return(plot)
}

this is inefficient of course, as if you have 5 plots, externalFunction will be called 5 times.

jonathon