4
votes

Barres tracées avec décalage de l'axe X pour les horodatages

Je veux tracer des horodatages avec des barres tracées, avec 1 barre indiquant une heure entière.

Mon problème est que les graduations sont centrées au milieu et je voudrais les déplacer vers l'extrémité gauche de les barres .

Lorsque le tracé n'est pas agrandi, ce n'est pas un problème, mais lors d'un zoom avant, d'autres étiquettes de graduation apparaîtront et elles seraient erronées.

EDIT: J'ai besoin de l'option barmode = 'overlay' car j'ai aussi d'autres traces à tracer, qui ne sont pas incluses dans cet exemple.

L'image ci-dessous illustre mon mise en page actuelle et attendue et voici quelques données pour créer ce graphique. (Certaines options que j'ai essayées sans succès sont également incluses dans la configuration de xaxis mais non commentées).

library(plotly)
library(lubridate)


df <- data.frame(
  ts = seq(as.POSIXct("2019-03-20 00:00:00"), by = "hour", length.out = 24),
  val = sample(1:100, 24)
)

plot_ly() %>% 
  add_bars(data = df, x = ~ts, y = ~val) %>% 
  layout(dragmode = "select", autosize = TRUE, selectdirection = "h",
                 barmode = 'overlay',
                 bargap = 0.05,
                 xaxis = list(ticks = "outside",
                              type = "date",
                              # tickson="boundaries",
                              # offset=1800,
                              tickmode = "auto",
                              title = ""
                              )) %>% 
  config(scrollZoom = TRUE)

 entrez la description de l'image ici


0 commentaires

3 Réponses :


1
votes

Par défaut, les barres sont centrées, je n'ai pas trouvé comment changer cela. Une alternative consiste à ajouter une deuxième barre, car quand il y a 2 barres pour chaque unité de l'axe x, une barre est à gauche de la graduation de l'axe et la seconde à droite (ce que vous essayez d'obtenir avec une barre) .

Pourquoi ne pas créer une deuxième barre invisible? :)

df <- data.frame(
  ts    = seq(as.POSIXct("2019-03-20 00:00:00"), by = "hour", length.out = 24),
  val   = sample(1:100, 24),
  val0  = 0 
)

plot_ly(df, type = 'bar') %>%
  add_trace(x = ~ts, y = ~val0) %>% 
  add_trace(x = ~ts, y = ~val) %>%
  layout(
    showlegend = FALSE
  ) %>% 
  config(scrollZoom = TRUE)

Cela créera une légende (car il y a 2 types de barres, une pour val et une pour val0), donc je l'ai supprimée.

 entrez la description de l'image ici


1 commentaires

Malheureusement, je ne peux pas faire cela, car j'ai besoin de barmode = 'overlay' car j'ai d'autres barres à tracer également, et les valeurs 0 seraient simplement superposées et tracées pour rien. Mais merci pour la suggestion.



1
votes

Les éléments suivants répondraient-ils à vos besoins?

Une des choses dont je profite parfois avec plotly est que vous pouvez afficher différentes valeurs dans text qui sont indépendamment de vos valeurs x et y utilisées pour tracer les données.

Dans ce cas, nous pouvons créer une colonne avec une valeur de temps de décalage, ts_x et tracez les valeurs x une demi-heure après l'heure de chaque ligne - Si vous avez une colonne pour chaque heure, cela aligne effectivement les barres à gauche.

library(plotly)

df <- data.frame(
  ts = seq(as.POSIXct("2019-03-20 00:00:00"), by = "hour", length.out = 24),
  val = sample(1:100, 24)
)

## Create a dummy column with x offset values
df$ts_x <- df$ts + 1800

plot_ly() %>% 
  ## Plot based on the dummy column
  add_bars(data = df, x = ~ts_x, y = ~val,
           ## Cover up our tracks by not showing true x value on hoverinfo
           hoverinfo = "text",
           ## Give text that includes the un-altered time values
           text = ~paste0("Time: ",format(ts, format = "%B %d, %Y %H:%M"),
                               "<br>Value: ",val)) %>% 
  layout(dragmode = "select", autosize = TRUE, selectdirection = "h",
         barmode = 'overlay',
         bargap = 0.05,
         xaxis = list(ticks = "outside",
                      type = "date",
                      tickmode = "auto",
                      title = ""
         )) %>% 
  config(scrollZoom = TRUE)


1 commentaires

Ce n'est en effet pas une mauvaise idée. Je vais regarder de plus près et le tester avec les données d'origine. Ma seule réserve est que j'ai environ 6 barplots à superposer et que je devrais alors créer une colonne supplémentaire pour chacun d'eux. Mais s'il n'y a pas d'autre option, c'est probablement la meilleure solution.



0
votes

Êtes-vous sûr de ne pas trop travailler sur l'ingénierie? La soustraction de 30 minutes me donne un joli graphique lors du zoom avant.

Je ne vous suggère pas de modifier les données, même si c'est ce que je fais dans le code. Une petite fonction dans l'appel pour ajouter des barres pourrait le résoudre? Si vous superposez d'autres données, cela pourrait créer un désordre, mais je voulais juste le suggérer.

library(plotly)
library(lubridate)

df2 <- data.frame(
  ts = seq(as.POSIXct("2019-03-20 00:00:00"), by = "hour", length.out = 24) - minutes(30),
  val = sample(1:100, 24)
)


plot_ly() %>% 
  add_bars(data = df2, x = ~ts, y = ~val) %>% 
  layout(dragmode = "select", autosize = TRUE, selectdirection = "h",
         barmode = 'overlay',
         bargap = 0.05,
         xaxis = list(ticks = "outside",
                      type = "date",
                      # tickson="boundaries",
                      # offset=1800,
                      tickmode = "auto",
                      title = ""
         )) %>% 
  config(scrollZoom = TRUE)


1 commentaires

J'obtiens les horodatages d'une base de données et je veux que les horodatages "corrects" soient affichés sous forme de pop-up. Donc, s'il n'y a pas d'option pour définir le décalage d'étiquette, je dois aller jusqu'à présent avec la réponse de @Matt Summersgill.