1

The scale does not change the way I want and the way I wrote in the code. Why is that? Can someone help? My goal is to have a tick and label for every year on the x axis and a scale from -6 to 3 on the y axis, also including ticks and labels.


Periode <- as.Date(website$Datum)
Index <-  website$KonSens

datebreaks <- seq(as.Date("1998-03-31"), as.Date("2022-06-30"), by = "1 month")

plot.Website <- 
  ggplot(data = website, aes(x = Periode, y = Index)) +
  scale_x_date(breaks = datebreaks) +
  scale_y_continuous(breaks = seq(-6,3,1), labels = c("-6", "-5", "-4", "-3", "-2", "-1", "0", "1", "2", "3"), limits = c(-6,4), n.breaks = 10)+
  theme(axis.text = element_text(color = "black", face = "bold", size = 10),
        axis.line.y = element_line(color = "black", size = 2),
        axis.line.x = element_blank(),
        axis.title = element_text(color = "black", face = "bold"),
        axis.title.y = element_text(angle = 180)) +
  geom_line(aes(y = Index), color = "#7AA489",size = 1.5) +
  geom_point(shape = 21, color = "#003478", fill = "#7AA489", size = 2.5, stroke = 1)


ggplotly(plot.Website, dynamicTicks = TRUE) %>%
  rangeslider(borderwidth = 1)

The breaks are not the same as in the code, wether on the x nor y axis

Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
  • The breaks are wrong with the ```ggplotly()```, are they also wrong in the ```ggplot()``` that you save in your ```plot.Website```? Also! ```scale_y_continuous()``` has an argument ```limits``` and an argument ```breaks```. ```limits``` determines the total lenght of your axis, while ```breaks``` allows you to specify the distance between the axis ticks. – Omniswitcher Sep 22 '22 at 13:20
  • they are correct in the ggplot() but not in the ggplotly(). And for the y axis I does'nt adapt to changes I make in limits or breaks. – Praktikant4 Sep 22 '22 at 13:23
  • I am not too familiar with ggplotly, but ggplot2 makes a static image with ```limits and breaks```. The ```dynamicTicks = TRUE``` probably overrules the limit and/or break rules from your ggplot2 plot. – Omniswitcher Sep 22 '22 at 13:28

1 Answers1

1

Plotly may ignore you regardless of what you do because it looks like you are asking for almost 300 tick labels on the x-axis. However, when you use ggplotly, date fields become character fields. (I don't know if this is from ggplot or if it's a Plotly-ism.)

After rendering the ggplotly object, you can replace the x in each trace and replace the majority of the arguments for layout.xaxis. Alternatively, you may find it to be a lot easier if you create this in Plotly, to begin with.

I've added the data I used because your question is not reproducible. It looks like you're new to SO; welcome to the community! If you want great answers quickly, it's best to make all questions reproducible. For example, sample data from the output of dput() or reprex::reprex(). Check it out: making R reproducible questions.

In the following code, the only parts you need to create the plot without the aesthetics are the first two piped: plot_ly() and add_lines().

I added comments to explain what different aspects of this code is doing. Additionally, I've broken down some of this a bit further after the code and plot image.

library(tidyverse)
library(plotly)

# Periode <- as.Date(website$Datum)  # data not provided
# Index <-  website$KonSens
set.seed(353)
website <- data.frame(
  Periode = sample(seq(as.Date("1998-03-31"), as.Date("2022-06-30"), by = "week"), 50),
                      Index = sample(runif(100, -4.5, 2.5), 50)) %>% 
  arrange(Periode)

plot_ly(type = "scatter", mode = "markers", 
        marker = list(color = "#7AA489", size = 8,
                      line = list(width = 2, color = "#003478")),
        data = website, x = ~Periode, y = ~Index) %>% 
  add_lines(line = list(width = 5, color = "#7AA489")) %>% 
  layout(xaxis = list(dtick = "M18",         # every 18 months
                      tickformat = "%b %Y"), # Abbrev Month, 4-digit year
         yaxis = list(range = c(-6, 3),      # show this range
                      zeroline = F,          # remove horizontal line at 0
                      showline = T),         # vertical line along y-axis
         showlegend = F) %>%                 # no legend
  htmlwidgets::onRender("function(el, x){.   # make the axis titles BOLD
    gimmeX = document.querySelector('g.infolayer g.g-xtitle text');
    gimmeY = document.querySelector('g.infolayer g.g-ytitle text');
    gimmeX.style.fontWeight = 'bold';
    gimmeY.style.fontWeight = 'bold';
  }") %>% 
  rangeslider(borderwidth = 1)

enter image description here

Specifying the Range on the y-axis

In Plotly, you won't need to set breaks and labels. You just need to define the range. If that's all you designated in the layout, it would like something like this.

layout(yaxis = list(range = c(-6, 3))

Non-Dynamic Date x-axis Tick Text Formatting

Labels on the x-axis can be specified to be labeled by month. However, like a commenter mentioned, you loose the dynamic date scaling done when you zoom. You can actually set the scaling date format for zooming ranges, as well. (I won't go into that in this answer, though.)

To specify the labels on the x-axis as every month by month, you would use layout.xaxis.dtick = "M1", every 18 months is M18, and so on. If you wanted to specify the appearance as the month and year, you can use the same formatting as used in as.Date, where %b is an abbreviated month name, and %Y is a four-digit year. If this was all you needed to set in the layout, it would look like this.

layout(xaxis = list(dtick = "M18",         # every 18 months
                    tickformat = "%b %Y")) # Abbrev Month, 4-digit year

Bold Axis Labels

Additionally, there isn't a parameter you can set to make the axis labels bold. It doesn't really matter if it's ggplotly or plot_ly.

However, you can use htmlwidgets::onRender to make this happen.

htmlwidgets::onRender("function(el, x){
    gimmeX = document.querySelector('g.infolayer g.g-xtitle text');
    gimmeY = document.querySelector('g.infolayer g.g-ytitle text');
    gimmeX.style.fontWeight = 'bold';
    gimmeY.style.fontWeight = 'bold';
  }")
Kat
  • 15,669
  • 3
  • 18
  • 51