Необходим доступ к / редактировать список plotly_build в R блестящий, чтобы вручную редактировать компоненты интерактивного сюжета - PullRequest
1 голос
/ 17 октября 2019

Я пытаюсь получить доступ к plotly_build реактивного графика, чтобы вручную отредактировать стандартные компоненты графика для дальнейшей настройки моего графика. Я могу сделать это простым сценарием .R, чтобы проверить функциональность изменений в сборке, но мне не удалось заставить его работать в R Shiny, который я создаю, и который включает реактивный сюжет.

Вкладка на включенной Shiny включает в себя selectizeInput () для функции, которую выбирает пользователь, которую Shiny использует для фильтрации фрейма данных и создания графика соответствующим образом. При этом графики стали немного запутанными как на ggplot, так и на графике (используя ggplotly для преобразования в сюжет). В конечном итоге я настроил ggplot настолько, насколько мог, но с помощью plotly_build () я вручную получил доступ к компонентам plotly, чтобы отредактировать такие вещи, как метки легенды и заголовок.

При тестировании вне Shiny я смог создать этот график, вручную изменив функцию фильтра. В Shiny, однако, поскольку есть пользовательский ввод, который управляет реактивным сюжетом, это создало огромный каскад проблем.

Вот упрощенный пример моей попытки:

library(shiny)
library(dplyr)
library(readr)
library(ggplot2)
library(plotly)
library(scales)
library(kableExtra)

ui <- fluidPage(

    # Application title
    titlePanel("DASHBOARD TITLE"),

    mainPanel(
       tabsetPanel(
          tabPanel("DATA PLOTS", 
                   selectizeInput("srvr", label = "Name", choices=NULL, options = list(placeholder = 'Search for a Name')),
                   plotlyOutput("entrance_exit_npl_plotly"))
        )
      )
)

server <- function(input, output, session) {

  entrance_exit_table_npl <- readRDS(file='path/filename.rds')

  updateSelectizeInput(session, 'srvr', choices = c(unique(entrance_exit_table_npl$ENTITYNM)), selected = 'DEFAULT OPTION',server = TRUE)

  # Storing user input$srvr
  selected_srvr <- reactive({as.character(input$srvr)})

  # Filtering based on user input
  servicer_data_npl <- reactive({
    filter(entrance_exit_table_npl, ENTITYNM==selected_srvr()) %>% 
      group_by(P_ENTITY, LN_CURR_ACVY_STRT_DT) %>% 
      select(contains("upb"))})

  # Creating ggplot object and attempt to capture plotly_build
  plot_servicer_build <- reactive({
    plotly_build(
        ggplot(servicer_data_npl(), aes(LN_CURR_ACVY_STRT_DT)) + 
        geom_line(aes(y=new_npl_entrance_upb, color = 'green', linetype = 'dotted')) +
        geom_line(aes(y=from_rpl_entrance_upb, color = 'green',linetype = 'dashed')) +
        geom_line(aes(y=total_entrance_upb, color = 'green', linetype = 'solid')) +
        geom_line(aes(y=npl_liqd_exit_upb, color = 'red', linetype = 'dotted')) +
        geom_line(aes(y=to_rpl_exit_upb, color = 'red', linetype = 'dashed')) +
        geom_line(aes(y=total_npl_exit_upb, color = 'red', linetype = 'solid')) +
        geom_line(aes(y=total_npl_upb, color = 'blue', linetype = 'dotdash')) +
        scale_y_continuous("UPB (Millions)",
                           labels = unit_format(unit = "M", big.mark = ",")) +
        scale_x_date("Activity Month",
                     breaks = date_breaks("1 month"),
                     date_labels = "%b-%Y",
                     expand = c(0,0)) +
        theme(plot.title = element_text(hjust = 0.5),
              axis.text.x = element_text(angle = 45)) +
        ggtitle(paste(selected_srvr(),"NPL Entrance and Exits")) +
        scale_color_identity(guide='legend') +
        scale_linetype_identity(guide='legend')
   )
 })

  # Editing plotly build. What I would like to happen, but will not work. This could also use the $ notation for subsetting, but this is how I did it to the plotly_build() list object outside of the Shiny. First, editing legend entry names, and second, removing the title of the legend.
    # plot_servicer_build[["x"]][["data"]][[1]][["name"]] <- "Entry Name 1"
    # plot_servicer_build[["x"]][["data"]][[2]][["name"]] <- "Entry Name 2"
    # plot_servicer_build[["x"]][["data"]][[3]][["name"]] <- "Entry Name 3"
    # plot_servicer_build[["x"]][["data"]][[4]][["name"]] <- "Entry Name 4"
    # plot_servicer_build[["x"]][["data"]][[5]][["name"]] <- "Entry Name 5"
    # plot_servicer_build[["x"]][["data"]][[6]][["name"]] <- "Entry Name 6"
    # plot_servicer_build[["x"]][["data"]][[7]][["name"]] <- "Entry Name 7"

    # plot_servicer_build[["x"]][["layout"]][["annotations"]][[1]][["text"]] <- " "

  # This was an attempt to subset a data frame resulting from a reactive function. I figured it wouldn't work, but I had seen stackoverflow posts where this was possible!
    # plot_servicer_build()$x$layout$annotations[[1]]$text <- " "

  # Output plotly rendering of graph and edit hover info
  output$entrance_exit_npl_plotly <- renderPlotly(
      ggplotly(plot_servicer_build()) %>% 
        style(hovertemplate = "Date: %{x} <br>UPB: $%{y}M"))
}

shinyApp(ui = ui, server = server)

Несколько проблем, с которыми я столкнулся:

  • Я не могу добавить другие строкикода, не привязанного к цепочке, присутствующей в renderPlotly (), так же, как и многие посты, которые я видел в своем исследовании. Мой требует запятую между каждой командой add, и это не поможет:
  • Мне вообще не удается получить доступ к объекту списка plotly_build ()
  • Подстановка реактивного объекта кажется довольно сложной.

Это ошибка, с которой я столкнулся при попытке использовать первоначальный синтаксис поднабора с помощью [[]], что я могу сделать за пределами Shiny (без реактивности):

Warning: Error in $: object of type 'closure' is not subsettable

Когда я пытаюсь использовать второй метод подмножества plot_servicer_build ():

Error in plot_servicer()$x$layout$annotations[[1]]$text <- " " : 
  invalid (NULL) left side of assignment

На этом пути было несколько других ошибок!

Есть ли кто-нибудь у кого есть предложения о том, как я могу внести эти изменения в plotly_build реактивного объекта ?! Я потратил так много времени на это, и мне кажется, что я становлюсь ближе, когда я пробую некоторые немного многообещающие методы в Интернете для подобных задач (например, plotyProxy ()), и я очень полон решимости получить этоработать, особенно потому, что я знаю, что код работает за пределами реактивного сюжета в Shiny! Я приветствую все и любые ваши мысли. Я прошу прощения за то, что не предоставил набор данных, но он запатентован, поэтому я должен быть осторожен.

Версии:

  • RStudio: 1.2.5001.3
  • Графика: 4.9.0 dev
  • Shiny: 1.3. 2
  • ggplot2: 3.1.1
  • R: 3.6.0

Спасибо!

...