Reputation: 3750
does anyone know how i can label the horizontal and/or vertical line on reactive ggplot in shiny?
All my data is based on filtered datatable, therefore the intercept changes depending on the input data. Filtered data is showed on the ggplot, furtehrmore the user can choose x and y axis to display. One of choices on x axis is date column: which makes it difficult (plus some of the columns are numbers/some factors).
My horizontal and vertical lines are reactive as well (depending on filtered data)
Code:
library(shiny)
library(shinydashboard)
library(ggplot2)
library(scales)
library(reshape2)
library(dplyr)
library(DT)
data_melt <- structure(list(Block = 1:20, Limits = structure(c(18L,
18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L,
18L, 18L, 18L, 18L, 18L, 18L), .Label = c("0.13", "0.15", "0.18",
"0.2", "0.21", "0.23", "0.25", "0.26", "0.28", "0.3", "0.32",
"0.37", "0.4", "0.45", "0.48", "0.5", "0.52", "0.55", "0.56",
"0.59", "0.6", "0.64", "0.7", "0.8", "1"), class = "factor"),
Date = structure(c(16439, 16439, 16439, 16439, 16439, 16439,
16439, 16439, 16439, 16439, 16439, 16439, 16439, 16439, 16439,
16439, 16439, 16439, 16439, 16439), class = "Date"), X = c(0.24,
0.25, 0.23, 0.24, 0.23, 0.24, 0.22, 0.24, 0.21, 0.22, 0.23, 0.24, NA_real_, NA_real_, NA_real_, 5.5, NA_real_,
NA_real_, NA_real_, 0.27)), .Names = c("Block", "Limits", "Date",
"X"), row.names = c(NA, 20L), class = "data.frame")
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(selectInput(inputId = "yaxis",
label = "Y-axis (Plots/Histogramm)",
choices = list("X" = "X"),
selected = c("X")),
selectInput(inputId = "xaxis",
label = "X-axis (Plots)",
choices = names(data_melt),
selected = "WertNr")),
dashboardBody(
fluidRow(
tabBox(status = "primary", width = NULL, height = "1000px",
tabPanel(title="Tabelle filtern", div(style = 'overflow-y: scroll; overflow-x: scroll;max-height: 950px; position:relative;',
dataTableOutput("tabelle"))),
tabPanel("plot", plotOutput("plot", height=800)))))
)
server <- function(input, output, session) {
output$tabelle <- renderDataTable({
datatable(data_melt,class = 'cell-border stripe', filter="top",
options = list(pageLength = 50, columnDefs = list(list(width = '200px', targets = "_all"), list(bSortable = FALSE, targets = "_all"))))
})
output$plot <- renderPlot({
filtered_data <- input$tabelle_rows_all
data_filt <- data_melt[filtered_data,]
vec <- quantile(data_filt[ ,input$yaxis], c(.00135,.50,.99865), na.rm = TRUE)
data_filt$Limits <- as.numeric(as.character(data_filt$Limits))
widedata <- subset(data_filt, select=c(input$xaxis, input$yaxis))
longdata <- melt(widedata, id.vars=c(input$xaxis), variable.name="Variables", value.name="Value_y")
longdata$WertNr <- as.numeric(1:nrow(longdata))
ggplot()+
geom_line(data=longdata, aes_string( x=input$xaxis, y="Value_y"),colour= "gray40", size=1.5) +
geom_hline(data=data_filt, aes(yintercept=(Limits*2)*0.75), linetype = "dotdash", size = 1, color="red") +
geom_hline(data=data_filt, aes(yintercept=0), linetype = "dotdash", size = 1, color="red") +
scale_y_continuous(breaks = pretty_breaks(n = 10)) +
theme(axis.text.y=element_text(size=15),
axis.text.x=element_text(size=15),
axis.title.x = element_text(size=18, face="bold"),
axis.title.y = element_text(size=18, face="bold"),
legend.position="bottom", legend.title=element_blank(),
legend.text=element_text(size=14))
})
}
shinyApp(ui = ui, server = server)
Thanks for any help!
I have tried geom_text
, annotate
, and even created separate data.frame
, however it just gives me an error, when the date on x axis is choosen.
toly <- ((data_filt$Limits*2)*0.75)
txty <- data.frame(x=1.5, y=toly[1], lab="OSG") in `renderPlot` and then
geom_text(data=txty, aes(label=lab), size=5, angle = 90, hjust = 0, vjust = 0) in ggplot --> is not working (i get error straight away)
Error: geom_text requires the following missing aesthetics: x, y
after adding x & y
geom_text(data=txty, aes(x=1.5, y=toly[1],label=lab), size=5, angle = 90, hjust = 0, vjust = 0)
It is working (However the label moves on the scale to match x=1.5, and i really would like it to stay on x axis in one place no matter of the x scaling) for numerical columns but for date column:
Error: Invalid input: date_trans works with objects of class Date only
i am trying to find solution that will let me label the horizontal line no matter what type of column has been choosen for x axis (numeric, date or factor) and let the label stay at the same position (next to the horizontal line) no matter what numbers are on scale
Upvotes: 0
Views: 2107
Reputation: 3750
i found the solution to my problem.
I had to define which columns are date, numerical and factor and then i used the If...else statements in server
, and created for each of them separate plot.
if (input$xaxis == "1st factor column" | input$xaxis == "2nd factor column"){
g <-ggplot(...) + geom_line() +
annotate("text", x=0.5, y=...)
}
else{
g <-ggplot(...) + geom_line() +
annotate("text", x=min(data_filt[ ,input$xaxis]), y= ...)
}g
Not elegant solution but its working :)
Upvotes: 1
Reputation: 3259
If the x-values of your plot have the type Date
, the x-values of your geom_text
object must also be an object of the type Date
. Try
geom_text(data=txty, aes(x=as.Date("2015-01-04"), y=toly[1], label=lab),
size=5, angle = 90, hjust = 0, vjust = 0)
and it works.
But anyway I did not really get what you intend to do. Please try to give a minimal example focusing on your problem the next time.
Upvotes: 1