如何使用 Shiny 中的 locator() 函数在绘图上绘制多边形?

How can I draw polygons on a plot using the locator() function in Shiny?

我正在尝试将用于虚拟南瓜雕刻的 R 脚本迁移到我的学生的 Shiny 应用程序。我希望该应用程序具有“点数”滑块,然后将其输入脚本中 polygon() 函数内的 locator() 函数。这个想法是,您可以 select 使用滑块的多边形顶点(点)的数量,然后单击绘图以绘制多边形。

该脚本在 R 中可以正常运行,但是当我尝试使用两个滑块的值作为 Shiny 中 locator() 的输入时,我 运行 遇到了麻烦。当我 运行 应用程序时,它显示以下错误来代替我的基本南瓜图:“错误:定位器 () 中的无效点数”

如何更正此问题,以便该应用程序能够在 Shiny 环境中正常运行?

这是我的 R 脚本:

    #Create base plot
par(bg=1, mar = c(0,0,0,0))
plot(c(0,0), cex=0, xlim=c(-1,1), ylim=c(1.5,0))
X <- runif(500,-1,1)
Y <- runif(500,0,1)
M <- rchisq(500,1)/20
points(Y~X, cex=M, pch=19, col= "white")
points(0,1.1, pch=19, col= "orange",cex=20)
polygon(c(-0.03, -0.08, -0.02, 0.03), c(0.86, 0.76, 0.78, 0.86),
        col = "darkgreen",
        border = "darkgreen",
        lwd = 3, lty = "solid")
#Use the mouse to carve the eyes, clicking at 4 points for each polygon
for (i in 1:2){
  polygon(locator(4),col=7)
}

#Use the mouse to carve the eyes, clicking at 3 points for each polygon
polygon(locator(3), col = 7)

#Now carve the mouth, clicking at 15 points (you can adjust the number of points inside the locator() function below)
polygon(locator(15), col = 7)

# Congratulations, you just carved your first virtual pumpkin with R! You're being a nerd for Halloween!

到目前为止,这是我的 Shiny 应用程序:

    library(shiny)

# Define UI for application that draws a histogram
ui <- fluidPage(

    # Application title
    titlePanel("Pumpkin Carving with Shiny R"),

    # Sidebar with a slider input for number of bins 
    sidebarLayout(
        sidebarPanel(
            sliderInput("points",
                        label = div(h3("Eyes"), em("Number of points:")),
                        min = 1,
                        max = 15,
                        value = 4),
            sliderInput("points1",
                        label = div(h3("Nose"), em("Number of points:")),
                        min = 1,
                        max = 15,
                        value = 10),
            sliderInput("points2",
                        label = div(h3("Mouth"), em("Number of points:")),
                        min = 1,
                        max = 15,
                        value = 10)
        ),

        # Show a plot of the generated distribution
        mainPanel(
           plotOutput("Plot")
        )
    )
)

# Define server logic required to draw a histogram
server <- function(input, output) {

    output$Plot <- renderPlot({
        par(bg=1, mar = c(0,0,0,0))
        plot(c(0,0), cex=0, xlim=c(-1,1), ylim=c(1.5,0))
        X <- runif(500,-1,1)
        Y <- runif(500,0,1)
        M <- rchisq(500,1)/20
        points(Y~X, cex=M, pch=19, col= "white")
        points(0,1, pch=19, col= "orange",cex=40)
        polygon(c(-0.05, -0.08, -0.02, 0.05), c(0.6, 0.44, 0.46, 0.6),
                col = "darkgreen",
                border = "darkgreen",
                lwd = 3, lty = "solid")
        
        #Draw eye polygons with locator() using input from the first slider
        for (i in 1:2){
            polygon(locator(points), col=7)
        }
        
        #Draw nose polygon with locator() using input from the first slider
            polygon(locator(points1), col=7)
        
        #Draw mouth polygon with locator() using input from the second slider
        polygon(locator(points2), col = 7)
    })
}

# Run the application 
shinyApp(ui = ui, server = server)

谢谢!

用户输入变量需要被调用为input$abc

试试这个

# Define server logic required to draw a histogram
server <- function(input, output) {
  
  output$Plot <- renderPlot({
    par(bg=1, mar = c(0,0,0,0))
    plot(c(0,0), cex=0, xlim=c(-1,1), ylim=c(1.5,0))
    X <- runif(500,-1,1)
    Y <- runif(500,0,1)
    M <- rchisq(500,1)/20
    points(Y~X, cex=M, pch=19, col= "white")
    points(0,1, pch=19, col= "orange",cex=40)
    polygon(c(-0.05, -0.08, -0.02, 0.05), c(0.6, 0.44, 0.46, 0.6),
            col = "darkgreen",
            border = "darkgreen",
            lwd = 3, lty = "solid")
    
    #Draw eye polygons with locator() using input from the first slider
    for (i in 1:2){
      polygon(locator(req(input$points)), col=7)
    }
    
    #Draw nose polygon with locator() using input from the first slider
    polygon(locator(input$points1), col=7)
    
    #Draw mouth polygon with locator() using input from the second slider
    polygon(locator(input$points2), col = 7)
  })
}