Créer un objet ggplotly avec un sous-titre

Oct 30 2020

Je trace un nuage de points avec ce ggplot()qui suit:

library(data.table)
library(plotly)
library(ggplot2)
library(lubridate)

dt.allData <- data.table(date = seq(as.Date('2020-01-01'), by = '1 day', length.out = 365),
                         DE = rnorm(365, 4, 1), Austria = rnorm(365, 10, 2), 
                         Czechia = rnorm(365, 1, 2), check.names = FALSE)

## Calculate Pearson correlation coefficient: ##
corrCoeff <- cor(dt.allData$Austria, dt.allData$DE,  method = "pearson", use = "complete.obs")
corrCoeff <- round(corrCoeff, digits = 2)

## Linear regression function extraction by creating linear model: ##
regLine <- lm(DE ~ Austria, data = dt.allData)

## Extract k and d values for the linear function f(x) = kx+d: ##
k <- round(regLine$coef[2], digits = 5) d <- round(regLine$coef[1], digits = 2)
linRegFunction <- paste0("y = ", d, " + (", k, ")x")

## PLOT: ##
p1 <- ggplot(data = dt.allData, aes(x = Austria, y = DE, 
                                    text = paste("Date: ", date, '\n',
                                                 "Austria: ", Austria, "MWh/h", '\n',
                                                 "DE: ", DE, "\u20ac/MWh"),
                                    group = 1)
      ) +
      geom_point(aes(color = ifelse(date >= now()-weeks(5), "#419F44", "#F07D00"))) +
      scale_color_manual(values = c("#F07D00", "#419F44")) +
      geom_smooth(method = "lm", se = FALSE, color = "#007d3c") +
      annotate("text", x = 10, y = 10,
               label = paste("\u03c1 =", corrCoeff, '\n',
                             linRegFunction), parse = TRUE) +
      theme_classic() +
      theme(legend.position = "none") +
      theme(panel.background = element_blank()) +
      xlab("Austria") +
      ylab("DE")+
      ggtitle("DE vs Austria") +
      theme(plot.title = element_text(hjust = 0.5, face = "bold"))

# Correlation plot converting from ggplot to plotly: #
plot <- plotly::ggplotly(p1, tooltip = "text")

ce qui donne ici le graphique suivant:

J'utilise annotate()pour représenter le coefficient de corrélation et la fonction de régression. Je définis les coordonnées xet ymanuellement afin que la sortie texte soit affichée au milieu en haut. Étant donné que j'ai certaines de ces tables de données dt.allDataqui ont des échelles d'axe différentes, je voudrais définir dans le tracé que le texte doit toujours être affiché au milieu en haut, en fonction de la mise à l'échelle de l'axe sans définir xet ycoordonner manuellement auparavant.

Réponses

4 ismirsehregal Oct 30 2020 at 16:56

Je suggérerais d' utiliser ggtitleet hjust = 0.5:

Modifier: utiliser plotly::layoutet une spanbalise pour créer le titre:

library(data.table)
library(ggplot2)
library(plotly)
library(lubridate)

dt.allData <- data.table(date = seq(as.Date('2020-01-01'), by = '1 day', length.out = 365),
                         DE = rnorm(365, 4, 1), Austria = rnorm(365, 10, 2), 
                         Czechia = rnorm(365, 1, 2), check.names = FALSE)

## Calculate Pearson correlation coefficient: ##
corrCoeff <- cor(dt.allData$Austria, dt.allData$DE,  method = "pearson", use = "complete.obs")
corrCoeff <- round(corrCoeff, digits = 2)

## Linear regression function extraction by creating linear model: ##
regLine <- lm(DE ~ Austria, data = dt.allData)

## Extract k and d values for the linear function f(x) = kx+d: ##
k <- round(regLine$coef[2], digits = 5) d <- round(regLine$coef[1], digits = 2)
linRegFunction <- paste0("y = ", d, " + (", k, ")x")

## PLOT: ##
p1 <- ggplot(data = dt.allData, aes(x = Austria, y = DE, 
                                    text = paste("Date: ", date, '\n',
                                                 "Austria: ", Austria, "MWh/h", '\n',
                                                 "DE: ", DE, "\u20ac/MWh"),
                                    group = 1)
) +
  geom_point(aes(color = ifelse(date >= now()-weeks(5), "#419F44", "#F07D00"))) +
  scale_color_manual(values = c("#F07D00", "#419F44")) +
  geom_smooth(method = "lm", formula = 'y ~ x', se = FALSE, color = "#007d3c") +
  # ggtitle(label = paste("My pretty useful title", '\n', "\u03c1 =", corrCoeff, '\n', linRegFunction)) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5)) +
  theme(legend.position = "none") +
  theme(panel.background = element_blank()) +
  xlab("Austria") +
  ylab("DE")

# Correlation plot converting from ggplot to plotly: #
# using span tag (directly in control of font-size):
span_plot <- plotly::ggplotly(p1, tooltip = "text") %>% layout(
    title = paste(
      '<b>My pretty useful title</b>',
      '<br><span style="font-size: 15px;">',
      '\u03c1 =<i>',
      corrCoeff,
      '</i><br>',
      linRegFunction,
      '</span>'
    ),
    margin = list(t = 100)
  )
span_plot

Edit: a ajouté l' supalternative selon cette réponse

# using sup tag:
sup_plot <- plotly::ggplotly(p1, tooltip = "text") %>% layout(
    title = paste(
      '<b>My pretty useful title</b>',
      '<br><sup>',
      "\u03c1 =<i>",
      corrCoeff,
      '</i><br>',
      linRegFunction,
      '</sup>'
    ),
    margin = list(t = 100)
  )
sup_plot

BrianLang Oct 30 2020 at 16:42

Tout d'abord, je commencerais par voir si quelque chose comme ça pourrait vous aider:

annotate("text", 
         x = mean(dt.allData$Austria, na.rm = TRUE), y = max(dt.allData$DE, na.rm = TRUE),
         label = paste("\u03c1 =", 
                       corrCoeff, '\n',
                       linRegFunction), 
         parse = TRUE,
         hjust = .5)

puis, dans le cas où vous souhaitez parcourir une liste de x,ypaires, vous voudrez éventuellement passer à la programmation fonctionnelle où vous passez des xcolonnes x1, x2, x3et des ycolonnes y1, y2, y3à une mapfonction qui extrait ensuite les informations pertinentes de chaque paire et les trace.