Personalizza R traccia plottamente i colori nelle sottotrame

Aug 24 2020

Ho un dataframe, che puoi ottenere con questo codice:

x = data.frame(metrics=c("type1", "type1", "type1","type1", "type1", "type1", "orders", "orders", "orders","orders", "orders", "orders", "mean","mean","mean","mean","mean","mean"), hr=c(6,7,8,6,7,8,6,7,8,6,7,8,6,7,8,6,7,8), actual=c(14,20,34,22,24,27,56,12,34,11,15,45,56,78,89,111,123,156), time_pos=c("today", "yesterday", "today", "yesterday", "today", "yesterday"))

Sulla base di una domanda precedente, ho finito con quanto segue:

plot <- function(df) {

  subplotList <- list()
  for(metric in unique(df$metrics)){ subplotList[[metric]] <- df[df$metrics == metric,] %>%
      plot_ly(
        x = ~ hr,
        y = ~ actual,
        name = ~ paste(metrics, " - ", time_pos),
        colors = ~ time_pos,
        hoverinfo = "text",
        hovertemplate = paste(
          "<b>%{text}</b><br>",
          "%{xaxis.title.text}: %{x:+.1f}<br>",
          "%{yaxis.title.text}: %{y:+.1f}<br>",
          "<extra></extra>"
        ),
        type = "scatter",
        mode = "lines+markers",
        marker = list(
          size = 7,
          color = "white",
          line = list(width = 1.5)
        ),
        width = 700,
        height = 620
      ) %>% layout(autosize = T,legend = list(font = list(size = 8)))
  }
  subplot(subplotList, nrows = length(subplotList), margin = 0.05)
}

e

plot(x)

mi dà questo:

Come puoi vedere, ha costruito sottotrame per ogni tipo di valori nella colonna "metriche" e inoltre, su ogni sottotrama ci sono due grafici a dispersione per ogni tipo di valore nella colonna "tempo" (oggi, ieri). Ma sono colori diversi. Come rendere i valori "oggi" e "ieri" dello stesso colore in ogni sottotrama? Quindi ci sono solo due tipi: "oggi" e "ieri" nella legenda e ogni sottotrama ha il titolo "tipo1", "ordini", "media"

Risposte

stefan Aug 24 2020 at 15:13

Ciò potrebbe essere ottenuto in questo modo:

  1. Per ottenere gli stessi colori in tutte le trame time_possulla mappa colorinvece che su colors.ie color = ~time_pos. Utilizzando colorsho impostato la tavolozza dei colori sui colori predefiniti (altrimenti ottengo un sacco di avvisi).

  2. La parte difficile è ottenere solo due voci di legenda per todaye yesterday. Prima mappa time_posin legendgroupmodo che le tracce in tutte le sottotrame vengano collegate. Secondo uso showlegendper mostrare la legenda solo per uno dei grafici, ad esempio la prima metrica.

  3. Per aggiungere titoli alle sottotrame utilizzo i add_annotationsseguenti post

    library(plotly)
    
    plot <- function(df) {
      .pal <- RColorBrewer::brewer.pal(3, "Set2")[c(1, 3)]
      subplotList <- list()
      for(metric in unique(df$metrics)){ showlegend <- metric == unique(df$metrics)[1]
        subplotList[[metric]] <- df[df$metrics == metric,] %>%
          plot_ly(
            x = ~ hr,
            y = ~ actual,
            color = ~ time_pos,
            colors = .pal,
            legendgroup = ~time_pos,
            showlegend = showlegend,
            hoverinfo = "text",
            hovertemplate = paste(
              "<b>%{text}</b><br>",
              "%{xaxis.title.text}: %{x:+.1f}<br>",
              "%{yaxis.title.text}: %{y:+.1f}<br>",
              "<extra></extra>"
            ),
            type = "scatter",
            mode = "lines+markers",
            marker = list(
              size = 7,
              color = "white",
              line = list(width = 1.5)
            ),
            width = 700,
            height = 620
          ) %>% 
          add_annotations(
            text = ~metrics,
            x = 0.5,
            y = 1,
            yref = "paper",
            xref = "paper",
            xanchor = "center",
            yanchor = "bottom",
            showarrow = FALSE,
            font = list(size = 15)
          ) %>% 
          layout(autosize = T, legend = list(font = list(size = 8)))
      }
      subplot(subplotList, nrows = length(subplotList), margin = 0.05)
    }
    
    plot(x)