gpt4 book ai didi

r - Shiny:ggplot 的动态颜色(填充)输入

转载 作者:行者123 更新时间:2023-12-01 09:50:26 25 4
gpt4 key购买 nike

我确实需要一些帮助作为帖子:Dynamic color input in shiny server没有完全回答我的问题。

我想在我 Shiny 的应用程序中选择动态颜色(填充)。我准备了一个示例代码:

library(shiny)
library(shinyjs)
library(reshape2)
library(ggplot2)

dat <- data.frame(matrix(rnorm(60, 2, 3), ncol=3))
dat <- melt(dat)

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')
),
server = function(input, output, session) {
cols <- reactive({
lapply(seq_along(unique(input$select)), function(i) {
colourInput(paste("col", i, sep="_"), "Choose colour:", "black")
})
})

output$myPanel <- renderUI({cols()})

cols2 <- reactive({
if (is.null(input$col_1)) {
cols <- rep("#000000", length(input$select))
} else {
cols <- unlist(colors())
}
cols})

testplot <- function(){
dat <- dat[dat$variable %in% input$select, ]
ggplot(dat, aes(x=variable,y=value, fill=cols2()[1])) + geom_boxplot()}

output$plot <- renderPlot({testplot()})

output$downloadplot <- downloadHandler(
filename ="plot.pdf",
content = function(file) {
pdf(file, width=12, height=6.3)
print(testplot())
dev.off()
})
}
))

我希望用户选择箱线图的填充颜色。颜色小部件的数量将根据 selectizeInput("select"... 中所选变量的数量出现。 .到目前为止,一切都运行良好,但是更进一步,我无法弄清楚如何将此颜色应用于 ggplot 等...

以下是我的问题:
  • 我怎么能将填充颜色连接到 ggplot 正确
  • 我可以制作 colourInput()的默认颜色对应于默认调色板(不是一种颜色 --> 在我的情况下是黑色)
  • 而不是 选择颜色 正文 colourInput(paste("col", i, sep="_"), "Choose colour:",我希望拥有变量(在本例中为 X1、X2 和 X3)的相应名称(从 selectizeInput 中选择变量)
  • 我也想要一个按钮,可以 全部重置 选择的颜色

  • 提前谢谢大家,我希望这可以解决

    干杯

    最佳答案

    这些是非常好的和具体的问题,我很高兴,希望能回答它们:)

    1. How i can connect the fill colour to ggplot correctly


    在这种情况下,我认为最好的方法是根据 variable 填充框。 (这是 react 性的)并添加一个新层 scale_fill_manual您可以在其中为不同的框指定自定义颜色。颜色的数量必须明显等于 variable 的级别数。 .这可能是最好的方法,因为您将始终拥有正确的图例。
    ggplot(dat, aes(x = variable, y = value, fill = variable)) + 
    geom_boxplot() +
    scale_fill_manual(values = cols)

    1. Can i make the default colour of colourInput() correspond to the default colour palette (not to one colour --> in my case is black)


    当然,你可以做到。

    首先,您需要知道 ggplot 使用的离散变量的默认颜色。为了生成这些颜色,我们将使用一个函数 gg_color_huethis 中找到很好的讨论。我已将其名称更改为 gg_fill_hue遵循 ggplot 约定。

    我们可以对 renderUI 内的所有内容进行编码我们首先指定选定的级别/变量。为了消除由于动态(并且可能以不同的顺序)生成的小部件而导致的明确性,我们对级别/变量的名称进行排序。

    然后我们用 gg_fil_hue 生成适当数量的默认颜色并将它们分配给适当的小部件。

    为方便起见,我们更改了 IDs这些小部件的 col + "varname"由 input$select 给出
    output$myPanel <- renderUI({ 
    lev <- sort(unique(input$select)) # sorting so that "things" are unambigious
    cols <- gg_fill_hue(length(lev))

    # New IDs "colX1" so that it partly coincide with input$select...
    lapply(seq_along(lev), function(i) {
    colourInput(inputId = paste0("col", lev[i]),
    label = paste0("Choose colour for ", lev[i]),
    value = cols[i]
    )
    })
    })

    3.Instead of Choose colour text in colourInput(paste("col", i, sep="_"), "Choose colour:", i would love to have the corresponding name (choosen variable from selectizeInput) of the variable (in this case X1, X2 and X3)



    它也在上面的代码中完成 - 简单粘贴。

    现在,让我们来看看由于生成的小部件的动态数量而出现的一个非常重要的问题。我们必须根据唯一的 colorInput 设置框的颜色并且可能有 1,2 甚至 10 个这些输入。

    我相信,解决这个问题的一个很好的方法是创建一个字符向量,其中包含指定我们通常如何访问这些小部件的元素。在下面的示例中,该向量如下所示: c("input$X1", "input$X2", ...) .

    然后使用非标准评估( evalparse )我们可以评估这些输入以获得具有选定颜色的向量,然后我们将其传递给 scale_fill_manual层。

    为了防止选择之间可能出现的错误,我们将使用函数“req”来确保带有颜色的向量的长度与所选级别/变量的长度相同。
    output$plot <- renderPlot({
    cols <- paste0("c(", paste0("input$col", sort(input$select), collapse = ", "), ")")
    # print(cols)
    cols <- eval(parse(text = cols))
    # print(cols)

    # To prevent errors
    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)

    })

    1. I would like as well to have a button which could reset all the choosen colours


    定义后 actionButton在客户端使用 ID="reset"我们创建了一个将更新 colorInput 的观察者s。

    我们的目标是返回一个带有 updateColourInput 的列表为每个可用的参数设置适当的参数 colourInput小部件。

    我们用所有选择的级别/变量定义一个变量,并生成适当数量的默认颜色。我们再次对向量进行排序以避免歧义。

    然后我们使用 lapplydo.call调用 updateColourInput具有作为列表给出的指定参数的函数。
    observeEvent(input$reset, {
    # Problem: dynamic number of widgets
    # - lapply, do.call

    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)

    # Function that produces default gg-colours is taken from this discussion:
    # https://stackoverflow.com/questions/8197559/emulate-ggplot2-default-color-palette
    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)) # sorting so that "things" are unambigious
    cols <- gg_fill_hue(length(lev))

    # New IDs "colX1" so that it partly coincide with input$select...
    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 = ", "), ")")
    # print(cols)
    cols <- eval(parse(text = cols))
    # print(cols)

    # To prevent errors
    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, {
    # Problem: dynamic number of widgets
    # - lapply, do.call

    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()
    })
    }
    ))

    关于r - Shiny:ggplot 的动态颜色(填充)输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38822863/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com