如何为使用 `coord_polar` 的 Shiny 交互式 ggplot 获取经过极坐标转换的点击数据?

How can I get polar-transformed click data for an Shiny interactive ggplot that uses `coord_polar`?

我正在开发一个带有极坐标的交互式极坐标 ggplot 条。最终目标是每个段中的条形 'rise' 满足鼠标在该扇区中单击的位置。

问题是极坐标 ggplots 的点击数据是笛卡尔坐标,而不是极坐标:绘图的左下角是 c(0,0),而不是中心。我怎样才能解决这个问题?有没有我可以使用的简单坐标变换,或者我可以设置的选项?

你可以看到应用程序的原型here,我的代码如下:

library(shiny)
library(ggplot2)
library(tibble)

xNames <-  c("Authentic", "Visionary", "Sustainable",
             "Inspiring", "Collaborative", "Raising up\nnew leaders")
segments <- length(xNames)


ui <- fluidPage(
mainPanel(
  plotOutput("evaluation_wheel", click = "plot_click"),
  p("Coordinates: "), textOutput("coordinates")
)
)

server <- function(input, output) {
  
  ## Plot evaluation wheel
  wheel_plot <- function(wheel.data){
    ggplot2::ggplot(wheel.data, aes(x = name, y = value)) + 
      geom_bar(stat = "identity") +
      scale_y_continuous(limits = c(0,10)) +
      coord_polar()
  }
  
  modify_plot_data <- function(click.value, old.plot.data){
    print(click.value)
    if(is.null(click.value))(click.value <- c(0,0))
    else{
      cat("x: ")
      print(click.value$x)
      cat("y: ")
      print(click.value$y)
      click.value <- c(click.value$x, click.value$y)
    }
    click.value <- floor(click.value)
    new.plot.data <- old.plot.data
    new.plot.data[click.value[1]] <- click.value[2]
    new.plot.data
  }
  
  plotData <- reactiveVal(integer(segments))
  
    output$evaluation_wheel <- renderPlot({
      # plotData <- modify_plot_data(input$plot_click, plotData)
      plotData(modify_plot_data(input$plot_click, plotData()))
      
      plotTibble <- tibble(
        name = xNames,
        value = plotData()
      )
      wheel_plot(plotTibble)
        
    })
    
    output$coordinates <- renderText({
      paste0("c(", input$plot_click$x, ",", input$plot_click$y, ")")
    })
}

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

您“只”需要从极投影转换回来。

 modify_plot_data <- function(click.value, old.plot.data){
    print(click.value)
    if(is.null(click.value))(click.value <- c(0,0))
    else{
      # Number of categories
      N_CAT = length(xNames)
      # Max value
      Y_LIMIT = 10 

      # Center and rescale X
      x=(click.value$x -( (N_CAT + 1) / 2 ) ) / N_CAT * Y_LIMIT / .4 

      # Center and rescale Y
      y=(click.value$y - ( Y_LIMIT / 2 ) ) / Y_LIMIT * Y_LIMIT / .4

      # Compute angle from X and Y
      angle = atan2( y, x)

      # Compute item number from angle (might be simplified)
      i = (( 5 * pi / 2 - angle ) %% ( 2 * pi )) / pi * ( N_CAT / 2 ) + 1

      # Compute length from angle and X
      j = min( Y_LIMIT, x / cos(angle) ) # length
      
      click.value <- c(i, j)
    }
    new.plot.data <- old.plot.data
    new.plot.data[floor(click.value[1])] <- click.value[2]
    new.plot.data
  }

同样要使其正常工作 as-is,您需要对您的值进行排序:

xNames <-  sort(c("Authentic", "Visionary", "Sustainable",
                  "Inspiring", "Collaborative", "Raising up\nnew leaders"))