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?
How to show a dynamic number of ggplot2 objects ...
Re: How to show a dynamic number of ggplot2 objects ...
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
jonathon
Re: How to show a dynamic number of ggplot2 objects ...
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
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 ...
i think you want something like this in your .r.yaml :
jonathon
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
Re: How to show a dynamic number of ggplot2 objects ...
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
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 ...
> 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
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