Блокировка сюжета в RStudio? - PullRequest
       12

Блокировка сюжета в RStudio?

0 голосов
/ 05 августа 2020

Я пытаюсь выполнить функцию, которая отображает некоторые данные, а затем воспроизводит звук (соответствующий этим данным) в RStudio. Однако кажется, что воспроизведение звука блокирует построение. Почему это?

plot.prod.df <- function(df, row) {
  # given a row number and a df, plot the prod df for that trial
  # create data
  print(paste0("plotting production data. trial: ", row))
  if(is.null(df$prod[[row]])){
    stop("Invalid trial")
  } 
  else {
    
    # get relevant production data
    prod.df <- data.frame("onset" = df$prod[[row]]$onset * 1000, 
                          "pitch" = df$prod[[row]]$pitch,
                          "error" = df$prod[[row]]$error_boolean)
    
    prod.df$error <- as.factor(prod.df$error)
    
    # get target notes
    target.notes <- str.mel.to.vector(df$stimuli.pitch[[row]], "-")
    
    # check if there were playbacktimes
    print(df$playback.times[[row]])
    if (any(is.na(df$playback.times[[row]]))) {
      print("no playback times on this trial")
      # plot
      ggplot(prod.df, aes(x=onset, y=pitch, color = error)) +
        theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
              panel.background = element_blank(), axis.line = element_line(colour = "black")) +
        geom_hline(yintercept = target.notes, color = magma.colors[4], size = 2, alpha = 0.7) + 
        geom_point() +
        scale_color_manual(values=c(magma.colors[1], magma.colors[2]))
    }
    else {
      playback.times <-  fromJSON(df$playback.times[[row]])[2:length(fromJSON(df$playback.times[[row]]))] # remove the default original playback
      print(playback.times)
      # plot
      ggplot(prod.df, aes(x=onset, y=pitch, color = error)) +
        theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
              panel.background = element_blank(), axis.line = element_line(colour = "black")) +
        geom_hline(yintercept = target.notes, color = magma.colors[4], size = 2, alpha = 0.7) + 
        geom_vline(xintercept = playback.times, color = magma.colors[5], size = 2, alpha = 0.7) + 
        geom_point() +
        scale_color_manual(values=c(magma.colors[1], magma.colors[2]))
    
    }
    
  }
  
}


# set up WavPlayer
sound::setWavPlayer("./sox/play")


play.seq <- function(midi_notes, length_of_each_note) {
  #print("playing sequence user heard")

  freqs <- midi_to_freq(midi_notes)
  sines <- lapply(freqs, sound::Sine, length_of_each_note)
  
  for (i in seq_along(1:length(sines))) {
    Sys.sleep(length_of_each_note)
    sound::play(cutSampleEnds(sines[[i]])) # cutSampleEnds removes cracks
  }
  
}


play.and.plot.trial <- function(df, row = NULL) {
  
  # if a row isn't specified, randomly select a row
  if (is.null(row)) {
    sampled_trial <- sample(1:nrow(df), 1)
  }
  else {
    sampled_trial <- row
  }
  
  print(paste0("no. trial to plot: ", sampled_trial))

  plot.prod.df(df, sampled_trial)
  play.seq(str.mel.to.vector(df$stimuli.pitch[[sampled_trial]], "-"), 0.25)
  
}

play.and.plot.trial(dat)

Я могу подтвердить, что, если я закомментирую следующую строку и запущу play.and.plot.trial (dat), она построит график:

play.seq(str.mel.to.vector(df$stimuli.pitch[[sampled_trial]], "-"), 0.25)

I я не уверен, почему это останавливает построение графика; я думаю, он выводит только на консоль.

Я также пробовал добавить Sys.sleep (5) перед воспроизведением звука, и это не помогло.

1 Ответ

1 голос
/ 05 августа 2020

TL; DR

print Grob:

play.and.plot.trial <- function(df, row = NULL) {
  # ...
  print(plot.prod.df(df, sampled_trial))
  play.seq(str.mel.to.vector(df$stimuli.pitch[[sampled_trial]], "-"), 0.25)
}

Обоснование

Вызовы ggplot(...) + geom_*(...) на самом деле не визуализируют в устройство graphi c. Рендеринг выполняется ggplot2:::print.ggplot. Попробуйте следующее:

gg <- ggplot(mtcars, aes(mpg, disp)) + geom_path()

Обратите внимание, как он не выводится на панель просмотра? Теперь, если вы наберете gg на консоли, он отобразится. Причина в том, что R попытается найти наиболее подходящий способ «распечатать» этот тип объекта. Используя метод отправки S3 в R, он использует class(gg) для поиска либо print.gg (не найдено), либо print.ggplot (находится в пакете ggplot2). Поскольку он находит последнее, он использует это.

(Если бы ни один не был найден, он использовал бы print.default.)

Это также применимо в for циклах, где, например, вы хотите создать несколько графиков.

В любом случае ответ состоит в явной визуализации. Из-за отправки метода S3 print(gg) по-прежнему будет вызывать ggplot2:::print.ggplot из-за того, как работает S3.

(Если вы когда-либо были в ситуации, когда у вас есть объект gg, который требует рендеринга, но вы не загрузили пространство имен ggplot2 с помощью library(ggplot2), вы можете использовать ggplot2:::print.ggplot(gg) явно. Или вы можете использовать его явно только потому, что вы хотите, чтобы ваш код был «декларативным» и недвусмысленным, поскольку не , зная, как S3 print(gg) может выглядеть волшебно.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...