这些是非常好的具体问题,我很高兴能够回答它们 :)
- 如何正确地将填充颜色连接到 ggplot?
在这种情况下,我认为最好的方式是根据变量(响应式变量)填充方块,并添加一个新层的
scale_fill_manual
,在其中为不同的方块指定自定义颜色。颜色的数量显然必须等于变量的级别数。这可能是最好的方法,因为您将始终拥有正确的图例。
ggplot(dat, aes(x = variable, y = value, fill = variable)) +
geom_boxplot() +
scale_fill_manual(values = cols)
- 我能否使colorInput()的默认颜色与默认颜色调色板相对应(不是一个颜色 -> 在我的情况下是黑色)
当然可以。
首先,您需要了解ggplot使用的离散变量的默认颜色。为了生成这些颜色,我们将使用此处讨论中发现的函数gg_color_hue
。我将其更改为gg_fill_hue
以遵循ggplot约定。
我们可以在renderUI
中编写所有代码,其中我们首先指定所选的级别/变量。为了消除由于动态(可能以不同顺序)生成的小部件而导致的歧义,我们对级别/变量的名称进行排序。
然后,我们使用gg_fil_hue
生成适当数量的默认颜色,并将其分配给适当的小部件。
为了简化事情,我们将这些小部件的ID
更改为col
+“varname”,该名称由input$select
给出
output$myPanel <- renderUI({
lev <- sort(unique(input$select))
cols <- gg_fill_hue(length(lev))
lapply(seq_along(lev), function(i) {
colourInput(inputId = paste0("col", lev[i]),
label = paste0("Choose colour for ", lev[i]),
value = cols[i]
)
})
})
3.将colorInput(paste("col", i, sep="_"), "选择颜色:")中的“选择颜色”文本更改为对应变量(在此示例中为X1,X2和X3)的相应名称(从selectizeInput中选择的变量)。
在上面的代码中也完成了这个操作 - 简单地粘贴。
现在,让我们看一个由于生成的小部件数量动态而引起的非常重要的问题。我们必须根据唯一的colorInput
设置盒子的颜色,可能有1、2或甚至10个这样的输入。
我认为,一种非常好的方法是创建一个字符向量,其中包含指定如何正常访问这些小部件的元素。在下面的示例中,该向量如下所示:c("input$X1", "input$X2", ...)
。
然后,使用非标准评估(eval
,parse
),我们可以评估这些输入以获取选定颜色的向量,然后将其传递给scale_fill_manual
层。
为了防止选择之间可能出现的错误,我们将使用函数'req'来确保颜色向量的长度与所选级别/变量的长度相同。
output$plot <- renderPlot({
cols <- paste0("c(", paste0("input$col", sort(input$select), collapse = ", "), ")")
cols <- eval(parse(text = cols))
req(length(cols) == length(input$select))
dat <- dat[dat$variable %in% input$select, ]
ggplot(dat, aes(x = variable, y = value, fill = variable)) +
geom_boxplot() +
scale_fill_manual(values = cols)
})
- 我希望有一个按钮,能够重置所有选择的颜色
在客户端定义actionButton
并设置ID="reset"
后,我们创建了一个观察器来更新colorInput
。
我们的目标是返回一个列表,其中包含每个可用的colourInput
小部件的合适参数化的updateColourInput
。
我们定义一个包含所有已选择的级别/变量的变量,并生成适当数量的默认颜色。然后我们再次对向量进行排序,以避免歧义。
然后我们使用lapply
和do.call
调用一个updateColourInput
函数,该函数使用指定的参数作为列表给出。
observeEvent(input$reset, {
lev <- sort(unique(input$select))
cols <- gg_fill_hue(length(lev))
lapply(seq_along(lev), function(i) {
do.call(what = "updateColourInput",
args = list(
session = session,
inputId = paste0("col", lev[i]),
value = cols[i]
)
)
})
})
完整示例:
library(shiny)
library(shinyjs)
library(reshape2)
library(ggplot2)
dat <- data.frame(matrix(rnorm(60, 2, 3), ncol=3))
dat <- melt(dat)
gg_fill_hue <- function(n) {
hues = seq(15, 375, length = n + 1)
hcl(h = hues, l = 65, c = 100)[1:n]
}
runApp(shinyApp(
ui = fluidPage(
selectizeInput("select", "Select:",
choices = as.list(levels(dat$variable)),
selected = "X1",
multiple = TRUE),
uiOutput('myPanel'),
plotOutput("plot"),
downloadButton('downloadplot', label = 'Download Plot'),
actionButton("reset", "Default colours", icon = icon("undo"))
),
server = function(input, output, session) {
output$myPanel <- renderUI({
lev <- sort(unique(input$select))
cols <- gg_fill_hue(length(lev))
lapply(seq_along(lev), function(i) {
colourInput(inputId = paste0("col", lev[i]),
label = paste0("Choose colour for ", lev[i]),
value = cols[i]
)
})
})
output$plot <- renderPlot({
cols <- paste0("c(", paste0("input$col", sort(input$select), collapse = ", "), ")")
cols <- eval(parse(text = cols))
req(length(cols) == length(input$select))
dat <- dat[dat$variable %in% input$select, ]
ggplot(dat, aes(x = variable, y = value, fill = variable)) +
geom_boxplot() +
scale_fill_manual(values = cols)
})
observeEvent(input$reset, {
lev <- sort(unique(input$select))
cols <- gg_fill_hue(length(lev))
lapply(seq_along(lev), function(i) {
do.call(what = "updateColourInput",
args = list(
session = session,
inputId = paste0("col", lev[i]),
value = cols[i]
)
)
})
})
output$downloadplot <- downloadHandler(
filename = "plot.pdf",
content = function(file) {
pdf(file, width = 12, height = 6.3)
print(testplot())
dev.off()
})
}
))
cols2 <- reactive({ if (is.null(input$col_1)) { cols <- rep("#000000",
,将会是ggplot中默认调色板的第一种颜色,即红色。它可以是任何其他调色板,对我来说并不重要,我只是不想一开始全部都是黑色或单一颜色。 - Mal_aaes_string(x="variable",y="value", fill=cols2()[1])
替换aes(x=variable,y=value, fill=cols2()[1])
,这样就可以了。 - NJBurgoError in [[: subscript out of bounds...
和Warning: Error in [: object of type 'closure' is not subsettable...
,并且没有任何绘图。 - Mal_a