I would like to create a ternary plot dashboard using Shiny. But I am stuck in this error. This code takes a CSV file and updates the three drop-down input. Then the ternary plot created has upon these three drop-down values.
The problem is when adding "geom_point()" to obj I get this error -> CoordTern requires the following missing aesthetics (tlr->xy) : z
The same but different problem when want to add stat_density_tern I get this error -> stat_density_tern requires the following missing aesthetics: z
library(shiny)
library(colourpicker)
library(ggplot2)
library(ggtern)
ui <- fluidPage(
titlePanel("TernaryPlot"),
fileInput("csv_file", "source", multiple = FALSE, accept = "csv",
width = NULL, buttonLabel = "Browse...",
placeholder = "No file selected"),
selectInput("x_val", "Choose x values:", choices=c()),
selectInput("y_val", "Choose y values:", choices=c()),
selectInput("z_val", "Choose z values:", choices=c()),
checkboxInput("show_point", "points", value = FALSE, width = NULL),
checkboxInput("show_dens", "density", value = FALSE, width = NULL),
plotOutput("ggtern")
)
server <- function(session,input, output) {
selectedData <- reactive({
inFile <- input$csv_file
if (is.null(inFile))
return(NULL)
df <- read.csv(inFile$datapath,na.strings = c("", "NA", "#N/A"))
updateSelectInput(session,"x_val","x series",colnames(df))
updateSelectInput(session,"y_val","y series",colnames(df))
updateSelectInput(session,"z_val","z series",colnames(df))
return(df)
})
T1 <- reactive({
if (is.null(selectedData()))
return(NULL)
temp <- selectedData()[input$x_val]
return (unlist(temp))
})
T2 <- reactive({
if (is.null(selectedData()))
return(NULL)
temp <- selectedData()[input$y_val]
return (unlist(temp))
})
T3 <- reactive({
if (is.null(selectedData()))
return(NULL)
temp <- selectedData()[input$z_val]
return (unlist(temp))
})
output$ggtern <- renderPlot({
if (is.null(selectedData()))
return(NULL)
if (is.null(T1()))
return(NULL)
x_s <- T1()
y_s <- T2()
z_s <- T3()
vec <- aes_string(x_s,y_s,z_s)
obj <- ggtern(data=selectedData(), vec)
if (input$show_point)
obj <- obj + geom_point()
if (input$show_dens)
obj <- obj + stat_density_tern(aes(fill=..level.., alpha=..level..), geom='polygon')
print(obj)
})
}
shinyApp(ui = ui, server = server)
I can do this in basic R but when trying to implement it as part of Shiny I get and error which I am not sure how to fix.
To make your app work you can simplify your code by getting rid of your reavtive expressions Tx
and pass the selected columns directly to ggtern
via aes_string
. Also to make ggtern
work with the geom_point
or geom_density
we have to name the aesthetics. Try this:
server <- function(session,input, output) {
selectedData <- reactive({
inFile <- input$csv_file
if (is.null(inFile))
return(NULL)
df <- read.csv(inFile$datapath,na.strings = c("", "NA", "#N/A"))
updateSelectInput(session,"x_val","x series",colnames(df))
updateSelectInput(session,"y_val","y series",colnames(df))
updateSelectInput(session,"z_val","z series",colnames(df))
return(df)
})
output$ggtern <- renderPlot({
if (is.null(selectedData()))
return(NULL)
req(input$x_val)
req(input$y_val)
req(input$z_val)
obj <- ggtern(data=selectedData(), aes_string(x = input$x_val, y = input$y_val, z = input$z_val))
if (input$show_point)
obj <- obj + geom_point()
if (input$show_dens)
obj <- obj + stat_density_tern(aes(fill=..level.., alpha=..level..), geom='polygon')
print(obj)
})
}