(RStudio) Блестящий plotOutput с ggplot ничего не дает - PullRequest
0 голосов
/ 18 октября 2018

Я пытался воссоздать знаменитый сюжет Ганса Рослинга, используя выход Shiny.Вывод оказался пустым на главной панели, где я разместил свой график без предупреждения.Можете ли вы помочь мне указать мою ошибку, пожалуйста?

library(gapminder)  
library(ggplot2)  
library(shiny)  
library(dplyr)  

ui <- shinyUI(fluidPage(  
   titlePanel("Life expectancy and GDP per capita from 1952 to 2007"),  
   sidebarLayout(  
  sidebarPanel(  
    p("Select year"),  
     sliderInput("yeartime",  
                 label = "Year",  
                 min = 1952,  
                 max = 2007,  
                 value = 1952,  
                 animate = animationOptions(interval = 500, loop = TRUE)
                 )),  
    mainPanel(
  plotOutput("Plot"),  
  )  
   )  
))

continent_colours <-c(Africa = "#BF590CFF", Americas = "#F80039FF", Asia = "#600071FF", 
                  Europe = "#3B9626FF", Oceania = "#4A51E0FF")  

server <- shinyServer(function(input, output) {  
   output$Plot <- renderPlot({  

p <- ggplot(gapminder, aes(x=lifeExp, y=gdpPercap, size = pop, color = continent))   
  + geom_point(data = filter(gapminder,gapminder$year == input$yeartime), aes(lifeExp, gdpPercap, size = pop, color = continent_colours)) 
  + ylim(30,100) 
   + labs(x="Life expectancy (years)", y = "GDP per capita (USD)", color = 'Continent',size = "Population (millions)")

   })


})


shinyApp(ui = ui, server = server)

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Есть несколько проблем с вашим кодом.

Во-первых, попробуйте проверить ggplot функцию в R.Отладка в Shiny довольно сложна.

  • В вашем ui есть запятая, которую необходимо удалить после plotOutput("Plot")
  • Используйте один и тот же набор данных при вызовах ggplot и geom_point.Я просто создал подмножество (gapminder_subset) и использовал его в обоих вызовах.
  • Вам не нужно присваивать свой график переменной p в блестящем.Без назначения это будет работать
  • Знак + для добавления элементов ggplot не должен находиться на новой строке.
  • Вы должны указать color и size вВызов geom_point.
  • Вы можете использовать цвета континента вместо одного цвета в вашем aes из geom_point, но в этом случае указанные цвета должны иметь ту же длину, что и ваши входные данные.Или (, как указал Эли Берков ), вы можете добавить раскраску с помощью элемента ggplot scale_colour_manual.

Вот рабочий пример:

library(gapminder)  
library(ggplot2)  
library(shiny)  
library(dplyr)  

ui <- shinyUI(fluidPage(  
  titlePanel("Life expectancy and GDP per capita from 1952 to 2007"),  
  sidebarLayout(  
    sidebarPanel(
      p("Select year"),
      sliderInput("yeartime",
                  label="Year",
                  min=1952,
                  max=2007,
                  value=1952,
                  animate=animationOptions(interval=500, loop=TRUE)
      )),
    mainPanel(
      plotOutput("Plot")  
    )  
  )  
))

continent_colours <- c(Africa="#BF590CFF", Americas="#F80039FF", Asia="#600071FF", 
                       Europe="#3B9626FF", Oceania="#4A51E0FF")  

server <- shinyServer(function(input, output) {  
  output$Plot <- renderPlot({  
    gapminder_subset <- gapminder[gapminder$year == input$yeartime, ]
    ggplot(gapminder_subset, aes(x=gdpPercap, y=lifeExp))+ 
        geom_point(aes(size=pop, color=continent))+
        scale_colour_manual(values=continent_colours)+
        ylim(30, 100)+
        labs(x="Life expectancy (years)", y="GDP per capita (USD)", 
             color='Continent', size="Population (millions)")
  })
})

shinyApp(ui=ui, server=server)
0 голосов
/ 18 октября 2018

Судя по комментариям, вы плохо защищаете себя от проблем с фильтрацией.Вот пример:

server <- shinyServer(function(input, output) {  
  thisdat <- eventReactive(input$yeartime, {
    req(input$yeartime)
    filter(gapminder, year == input$yeartime)
  })

  output$Plot <- renderPlot({
    req(thisdat())
    p <- ggplot(thisdat()) +
      geom_point(aes(lifeExp, gdpPercap, size = pop, color = continent_colours)) +
      ylim(30,100) +
      labs(x="Life expectancy (years)", y = "GDP per capita (USD)", color = 'Continent',size = "Population (millions)")
    print(p)
  })

})

Пошаговое руководство по некоторым вопросам:

  • Не используйте gapminder$ в filter, только имена столбцов.Он будет работать, когда вы не делаете ничего фантастического, но он побеждает некоторые преимущества, которые dplyr пытается сделать для вас, и сломается, если вы выполните какую-либо группировку или обобщение.

    filter(gapminder, gapminder$year == input$yeartime)  # wrong
    filter(gapminder, year == input$yeartime)            # right
    
  • Проверка (как блестяще это называется) "правдивых" данных с использованием req.Это предотвращает неправильное ввод данных от ваших данных и / или графиков (seq ?req).Например, если input$yeartime не установлено и, следовательно, NULL, thisdat не обновляется.Аналогичным образом, если thisdat() возвращает пустое значение data.frame, остальная часть функции печати будет пропущена (которая должна очистить тиски графика, приводящие к ошибке на консоли).

  • Я сломалвыведите данные в свой собственный реактивный блок, ожидая, что вы захотите сделать что-то еще с данными.Например, нередко иметь небольшую сводную таблицу и / или «карточку» на панели инструментов с краткой сводной статистикой.Для этого потребуется, чтобы этот дополнительный компонент повторно отфильтровал данные для своего материала.Теперь, все, что хочет увидеть, какие данные наносятся на график, может зависеть от thisdat() (выглядит / действует как функция), и побочным эффектом является то, что все, что зависит от thisdat(), также выиграет от единственного req(input$yeartime), больше ничего не нужно (если явно не используется в другом месте).

  • Я переместил объект данных с geom_point на ggplot(...).Вы, конечно, можете переместить его назад, но если вы не собираетесь использовать нефильтрованные данные из gapminder, просто придерживайтесь ggplot() + geom_point(data=thisdat(), aes(...)) + ....Вам не нужно указывать aes(...) дважды с этой визуализацией.(В любом случае, вам нужны только данные, перечисленные один раз.)

  • Нюанс ggplot2, я добавил print(p) в конце.Вы еще не достигли этого места, но, возможно, вам это понадобится, в конце концов.

  • Незначительная точка, но я переместил все + в конец строк, начиная с началаследующий.Возможно, это немного стилистично, но я знаю, что бывают случаи, когда парсер будет жаловаться / ломаться.(Это также очищает отступы в большинстве R-friendly редакторов.)

Я не внес никаких изменений в ваш ui компонент.

...