#
# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
# http://shiny.rstudio.com/
#
library(shiny)
library(shinythemes)
library(ggplot2)
make_legend_tab <- function(.label, .name, .title.text, .is.title) {
.full <- function(.l) {
stringr::str_c("legend", .label, .l, sep = "_")
}
objs <- list(title = .name)
objs <- c(objs, list(br()))
if (.is.title) {
objs <- c(objs, list(
splitLayout(
cellWidths = c("60%", "40%"),
checkboxInput(.full("remove"), "Remove the legend"),
checkboxInput(.full("contin"), "Continuous?")
),
sliderInput(.full("ncol"), "Number of columns:",
min = 1, max = 40, value = 2, step = 1
),
br(),
textInput(.full("text"), "Title text:", .title.text, placeholder = "Samples")
))
}
objs <- c(objs, list(
sliderInput(.full("size"), "Text size:",
min = 1, max = 40, value = ifelse(.is.title, 16, 11), step = .5
),
sliderInput(.full("hjust"), "Text horizontal adjustment:",
min = 0, max = 1, value = 0, step = .05
),
sliderInput(.full("vjust"), "Text vertical adjustment:",
min = -4, max = 4, value = .5, step = .25
),
sliderInput(.full("angle"), "Text angle:",
min = 0, max = 90, value = 0, step = 1
),
selectInput(
.full("face"), "Face:",
list(Plain = "plain", Bold = "bold", Italic = "italic", "Bold Italic" = "bold.italic")
)
))
do.call(tabPanel, objs)
}
# Define UI for application that draws a histogram
ui <- fluidPage(
theme = shinytheme("cosmo"),
titlePanel("FixVis: make your plots publication-ready already!"),
sidebarLayout(
sidebarPanel(
downloadButton("save_plot", "Save"),
actionButton("console_plot", "Plot to R console"),
br(),
br(),
tabsetPanel(
tabPanel(
"General",
br(),
textOutput("save_text"),
br(),
# textOutput("save_text2"),
# br(),
sliderInput("plot_width", "Plot width (in):", min = 2, max = 24, value = 10),
sliderInput("plot_height", "Plot height (in):", min = 2, max = 20, value = 6),
checkboxInput("coord_flip", "Flip coordinates"),
# checkboxInput("do_interactive", "Interactive plot"),
selectInput(
"ggplot_theme", "Theme",
list(
"Linedraw",
"Black-white",
"Grey / gray",
"Light",
"Dark",
"Minimal",
"Classic"
)
)
),
tabPanel(
"Title & subtitle",
br(),
tabsetPanel(
tabPanel(
"Title",
br(),
textInput("title_text", "Title text:", "Diamonds dataset visualisation", placeholder = "Gene usage"),
sliderInput("title_text_size", "Title text size:",
min = 1, max = 40, value = 25, step = .5
),
sliderInput("title_text_hjust", "Title text horizontal adjustment:",
min = 0, max = 1, value = 0, step = .05
),
sliderInput("title_text_vjust", "Title text vertical adjustment:",
min = -4, max = 4, value = .5, step = .25
),
sliderInput("title_text_angle", "Title text angle:",
min = 0, max = 90, value = 0, step = 1
),
selectInput(
"title_face", "Face:",
list(Plain = "plain", Bold = "bold", Italic = "italic", "Bold Italic" = "bold.italic")
)
),
tabPanel(
"Subtitle",
br(),
textAreaInput("subtitle_text", "Subtitle text:", "Load it via data(dataset)",
placeholder = "Frequency of Variable gene segments presented in the input samples"
),
sliderInput("subtitle_text_size", "Subtitle text size:",
min = 1, max = 40, value = 16, step = .5
),
sliderInput("subtitle_text_hjust", "Subtitle text horizontal adjustment:",
min = 0, max = 1, value = 0, step = .05
),
sliderInput("subtitle_text_vjust", "Subtitle text vertical adjustment:",
min = -4, max = 4, value = .5, step = .25
),
sliderInput("subtitle_text_angle", "Subtitle text angle:",
min = 0, max = 90, value = 0, step = 1
),
selectInput(
"subtitle_face", "Face:",
list(Plain = "plain", Bold = "bold", Italic = "italic", "Bold Italic" = "bold.italic")
)
)
)
),
tabPanel(
"Legends",
br(),
selectInput(
"legend_position", "Legend position",
list(
"right",
"top",
"bottom",
"left"
)
),
selectInput(
"legend_box", "Legend arrangement",
list(
"vertical",
"horizontal"
)
),
tabsetPanel(
tabPanel(
"Color",
tabsetPanel(
make_legend_tab("col_title", "Title (color)", "Colour", T),
make_legend_tab("col_text", "Labels (color)", "", F)
)
),
tabPanel(
"Fill",
tabsetPanel(
make_legend_tab("fill_title", "Title (fill)", "Cut", T),
make_legend_tab("fill_text", "Labels (fill)", "", F)
)
),
tabPanel(
"Size",
tabsetPanel(
make_legend_tab("size_title", "Title (size)", "Clarity", T),
make_legend_tab("size_text", "Labels (size)", "", F)
)
),
tabPanel(
"Shape",
tabsetPanel(
make_legend_tab("shape_title", "Title (shape)", "Cut", T),
make_legend_tab("shape_text", "Labels (shape)", "", F)
)
),
tabPanel(
"Linetype",
tabsetPanel(
make_legend_tab("linetype_title", "Title (linetype)", "Linetype", T),
make_legend_tab("linetype_text", "Labels (linetype)", "", F)
)
)
)
),
tabPanel(
"X axis",
br(),
tabsetPanel(
tabPanel(
"X title",
br(),
textInput("x_text", "X axis label:", "Carat", placeholder = "V genes"),
checkboxInput("apply_x2y", "Apply X axis settings to Y axis"),
br(),
sliderInput("x_title_size", "X axis title text size:",
min = 1, max = 40, value = 16, step = .5
),
sliderInput("x_title_hjust", "X axis title text horizontal adjustment:",
min = 0, max = 1, value = 0.5, step = .05
),
sliderInput("x_title_vjust", "X axis title text vertical adjustment:",
min = -4, max = 4, value = .5, step = .25
),
sliderInput("x_title_angle", "X axis title text angle:",
min = 0, max = 90, value = 0, step = 1
),
selectInput(
"x_title_face", "Face:",
list(Plain = "plain", Bold = "bold", Italic = "italic", "Bold Italic" = "bold.italic")
)
),
tabPanel(
"X ticks",
br(),
sliderInput("x_text_size", "X axis text size:",
min = 1, max = 40, value = 11, step = .5
),
sliderInput("x_text_hjust", "X axis text horizontal adjustment:",
min = -2, max = 2, value = .5, step = .1
),
sliderInput("x_text_vjust", "X axis text vertical adjustment:",
min = -4, max = 4, value = .5, step = .25
),
sliderInput("x_text_angle", "X axis text angle:",
min = 0, max = 90, value = 0, step = 1
),
selectInput(
"x_text_face", "Face:",
list(Plain = "plain", Bold = "bold", Italic = "italic", "Bold Italic" = "bold.italic")
)
)
)
),
tabPanel(
"Y axis",
br(),
tabsetPanel(
tabPanel(
"Y title",
br(),
textInput("y_text", "Y axis label:", "Price", placeholder = "Gene frequency"),
checkboxInput("apply_y2x", "Apply Y axis settings to X axis"),
br(),
sliderInput("y_title_size", "Y axis title text size:",
min = 1, max = 40, value = 16, step = .5
),
sliderInput("y_title_hjust", "Y axis title text horizontal adjustment:",
min = 0, max = 1, value = 0.5, step = .05
),
sliderInput("y_title_vjust", "Y axis title text vertical adjustment:",
min = -4, max = 4, value = .5, step = .25
),
sliderInput("y_title_angle", "Y axis title text angle:",
min = 0, max = 90, value = 90, step = 1
),
selectInput(
"y_title_face", "Face:",
list(Plain = "plain", Bold = "bold", Italic = "italic", "Bold Italic" = "bold.italic")
)
),
tabPanel(
"Y ticks",
br(),
sliderInput("y_text_size", "Y axis text size:",
min = 1, max = 40, value = 11, step = .5
),
sliderInput("y_text_hjust", "Y axis text horizontal adjustment:",
min = -2, max = 2, value = .5, step = .1
),
sliderInput("y_text_vjust", "Y axis text vertical adjustment:",
min = -4, max = 4, value = .5, step = .25
),
sliderInput("y_text_angle", "Y axis text angle:",
min = 0, max = 90, value = 0, step = 1
),
selectInput(
"y_text_face", "Face:",
list(Plain = "plain", Bold = "bold", Italic = "italic", "Bold Italic" = "bold.italic")
)
)
)
)
)
),
mainPanel(
uiOutput("main_plot", style = "position:fixed;")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output, session) {
data("diamonds")
.plot <- qplot(x = carat, y = price, fill = cut, shape = cut, color = color, size = clarity, data = diamonds[sample.int(nrow(diamonds), 5000), ]) + theme_classic()
create_plot <- function(input) {
# TODO: make automatic detection of available themes from ggplot2 and other packages
choose_theme <- function(theme_label) {
switch(theme_label,
Linedraw = theme_linedraw(),
`Black-white` = theme_bw(),
`Grey / gray` = theme_gray(),
`Light` = theme_light(),
`Dark` = theme_dark(),
`Minimal` = theme_minimal(),
`Classic` = theme_classic()
)
}
check_empty_str <- function(.str) {
if (.str == "" || .str == "\n" || .str == "\t") {
NULL
} else {
.str
}
}
get_legend_params <- function(.input, .label) {
.get <- function(.l) {
.input[[stringr::str_c("legend", .label, .l, sep = "_")]]
}
.remove <- .get("title_remove")
if (.remove) {
F # return F to pay respects (please remove it in the next release)
} else {
guide_fun <- guide_legend
if (.get("title_contin")) {
guide_fun <- guide_colorbar
}
guide_fun(
title = .get("title_text"),
ncol = .get("title_ncol"),
title.theme = element_text(
size = .get("title_size"),
hjust = .get("title_hjust"),
vjust = .get("title_vjust"),
angle = .get("title_angle"),
face = .get("title_face")
),
label.theme = element_text(
size = .get("text_size"),
hjust = .get("text_hjust"),
vjust = .get("text_vjust"),
angle = .get("text_angle"),
face = .get("text_face")
)
)
}
}
.plot <- .plot +
choose_theme(input$ggplot_theme) +
labs(
x = check_empty_str(input$x_text),
y = check_empty_str(input$y_text),
title = check_empty_str(input$title_text),
subtitle = check_empty_str(input$subtitle_text),
fill = input$legend_text,
color = input$legend_text
) +
guides(
col = get_legend_params(input, "col"),
fill = get_legend_params(input, "fill"),
size = get_legend_params(input, "size"),
shape = get_legend_params(input, "shape"),
linetype = get_legend_params(input, "linetype")
) +
theme(
plot.title = element_text(
size = input$title_text_size,
hjust = input$title_text_hjust,
vjust = input$title_text_vjust,
angle = input$title_text_angle,
face = input$title_face
),
plot.subtitle = element_text(
size = input$subtitle_text_size,
hjust = input$subtitle_text_hjust,
vjust = input$subtitle_text_vjust,
angle = input$subtitle_text_angle,
face = input$subtitle_face
),
legend.position = input$legend_position,
legend.box = input$legend_box,
axis.title.x = element_text(
size = input$x_title_size,
hjust = input$x_title_hjust,
vjust = input$x_title_vjust,
angle = input$x_title_angle,
face = input$x_title_face
),
axis.title.y = element_text(
size = input$y_title_size,
hjust = input$y_title_hjust,
vjust = input$y_title_vjust,
angle = input$y_title_angle,
face = input$y_title_face
),
axis.text.x = element_text(
size = input$x_text_size,
hjust = input$x_text_hjust,
vjust = input$x_text_vjust,
angle = input$x_text_angle,
face = input$x_text_face
),
axis.text.y = element_text(
size = input$y_text_size,
hjust = input$y_text_hjust,
vjust = input$y_text_vjust,
angle = input$y_text_angle,
face = input$y_text_face
)
)
if (input$coord_flip) {
.plot <- .plot + coord_flip()
}
.plot
}
output$save_text <- renderText({
'To save the plot, press the "Save" button above or drag-n-drop
the plot to your Desktop or into any file manager (Finder, File Explorer, etc.)'
})
output$save_text2 <- renderText({
'Note: saving via the "Save" button will be different from the drag-n-drop method
due to R\'s peculiar properties.'
})
output$main_plot <- renderUI({
# if (input$do_interactive) {
# output$main_plot_helper = renderPlotly(ggplotly(create_plot(input)))
# plotlyOutput("main_plot_helper")
# } else {
output$main_plot_helper <- renderPlot(create_plot(input))
plotOutput("main_plot_helper", width = input$plot_width * 72, height = input$plot_height * 72)
# }
})
#
# Assign X settings to Y
#
observe({
if (!is.null(input$apply_x2y)) {
if (input$apply_x2y) {
updateSliderInput(session, "y_title_size", value = input$x_title_size)
updateSliderInput(session, "y_title_hjust", value = input$x_title_size)
updateSliderInput(session, "y_title_vjust", value = input$x_title_size)
updateSliderInput(session, "y_title_angle", value = input$x_title_size)
updateSliderInput(session, "y_text_size", value = input$x_text_size)
updateSliderInput(session, "y_text_hjust", value = input$x_text_size)
updateSliderInput(session, "y_text_vjust", value = input$x_text_size)
updateSliderInput(session, "y_text_angle", value = input$x_text_size)
}
}
})
#
# Vice versa: assign Y settings to X
#
observe({
if (!is.null(input$apply_y2x)) {
if (input$apply_y2x) {
updateSliderInput(session, "x_title_size", value = input$y_title_size)
updateSliderInput(session, "x_title_hjust", value = input$y_title_hjust)
updateSliderInput(session, "x_title_vjust", value = input$y_title_vjust)
updateSliderInput(session, "x_title_angle", value = input$y_title_angle)
updateSliderInput(session, "x_text_size", value = input$y_text_size)
updateSliderInput(session, "x_text_hjust", value = input$y_text_hjust)
updateSliderInput(session, "x_text_vjust", value = input$y_text_vjust)
updateSliderInput(session, "x_text_angle", value = input$y_text_angle)
}
}
})
observeEvent(input$console_plot, {
plot(create_plot(input))
})
#
# Save plots
#
output$save_plot <- downloadHandler(
filename = paste0("plot shiny ", Sys.time(), ".png"),
content = function(file) {
ggsave(file, plot = create_plot(input), width = input$plot_width, height = input$plot_height, device = "png")
}
)
}
# Run the application
shinyApp(ui = ui, server = server)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.