Search code examples
rplotlyr-plotly

R Plotly multi line plot x axis label


I have a very specific question that relates to multi-line plotly plots in R. I found many questions that relate to bar charts, but nothing close to my current situation. I have the following simplified dataframe and code:

df <- data.frame(SEC_LABEL = c("3M","5Y",'10Y'), SEC1_VALUES = c(1.1, 1.4, 1.6), SEC2_VALUES = c(2.3, 2.6, 3.1), SORT=c(1,2,3))
color_line1 <- "#66C2A5"  #('rgb(102, 194, 165)')
  color_line2 <- "#8DA0CB" #('rgb(110, 194, 165)')

unique_line_names_1 <- "line1"
unique_line_names_2 <- "line2"

x_label < - as.character(df$SEC_LABEL)

p <- plot_ly(data = df, x = ~SORT) %>%
      # Time series chart
      add_lines(y = ~SEC1_VALUES, line = list(color = color_line1, width = 3),
                hoverinfo = unique_line_names_1, text = unique_line_names_1, name = unique_line_names_1)  %>%

      add_lines(y = ~SEC2_VALUES, line = list(color = color_line2, width = 3),
                hoverinfo = unique_line_names_2, text = unique_line_names_2, name = unique_line_names_2) %>%

      layout(title=paste0("Curves"),
             showlegend = TRUE,
             margin = list(l=30, r = 20, b = 30, t = 30, pad =1),
             legend = list(x = 0, y = 0.1, 
                           font = list(size = 8),
                           #orientation = 'h',
                           bgcolor ='transparent' ),
             xaxis=list(title='',
                        showline = FALSE,
                        zeroline = FALSE,
                        showticklabels = T,
                        showgrid = FALSE,
                        ticktext = x_label, 
                        gridwidth =0
                        #gridcolor = toRGB("gray50")
                        ),
             yaxis=list(title='',
                        showline = F,
                        zeroline = FALSE,
                        showgrid = T,
                        gridwidth =2)
             )

For some reasons the ticks on the x-axis are not re-labeled using the values in vector 'x_label'. (By the way, the only reason why I use as x-axis the SORT column instead of the SEC_LABEL column is because otherwise the x-axis get alphabetically sorted. Ideally, the desired ordering should be: 3M, 5Y, 10Y, but after having spent two hours, I realized I couldn't fix it). Thanks for the help


Solution

  • A I already mentioned in my comment the simple solution is to use an ordered factor, i.e.

    df$SEC_LABEL <- factor(df$SEC_LABEL, levels = x_label)
    

    and map SEC_LABEL on x. This way you get a categorical axis with categories in the wanted order.

    However, I had a look in the plotly docs using schema(). According the specs of plotly ticktext

    Sets the text displayed at the ticks position via tickvals. Only has an effect if tickmode is set to array. Used with tickvals.

    Hence to get your approach to work you have to set the tickmode to "array" in layout and also set the tickvals, i.e to c(1, 2, 3) in your case. After these adjustments your approach will also work.