Search code examples
rplotlylogarithm

plotly line chart with zero logarithmic scale


does anyone know how to deal with line charts in log scale where there are zero values in plotly? The lines sort of just disappear.

library(tidyverse)
library(lubridate)
library(plotly)

df2 <- tibble::tribble(
  ~SAMPLE_DATE, ~REPORT_RESULT_VALUE,
  "2018-10-04",                 0.05,
  "2019-05-05",                 0.01,
  "2019-10-04",                    0,
  "2020-06-05",                 0.01,
  "2020-09-11",                    0,
  "2021-04-23",                    0,
  "2022-05-08",                 0.06 ) %>% 
  mutate(SAMPLE_DATE = ymd(SAMPLE_DATE))


plot_ly(data = df2) %>%
  add_trace(x = ~SAMPLE_DATE,
            y = ~REPORT_RESULT_VALUE,
            mode = "lines+markers") %>%
  layout(xaxis = list(title = 'Sample date'),
         yaxis = list(title = "Concentration (mg/L)",
                      type = "log"))

enter image description here

I found a similar post in the plotly forum a while ago, but no solution: https://community.plotly.com/t/line-chart-with-zero-in-logarithmic-scale/40084

-----------------------

An extra example based on Jon Spring's edited answer.

df3 <- tibble::tribble(
  ~SAMPLE_DATE, ~REPORT_RESULT_VALUE, ~CHEMICAL_NAME,
  "2018-10-04",                 0.05, "a",
  "2019-05-05",                 0.01, "a",
  "2019-10-04",                    0, "a",
  "2020-06-05",                 0.01, "a",
  "2020-09-11",                    0, "a",
  "2021-04-23",                    0, "a",
  "2022-05-08",                 0.06, "a",
  "2018-10-04",                 95, "b",
  "2019-05-05",                 90, "b",
  "2019-10-04",                    80, "b",
  "2020-06-05",                 91, "b",
  "2020-09-11",                    90, "b",
  "2021-04-23",                    90, "b",
  "2022-05-08",                 96, "b",
  "2018-10-04",                 9.5, "c",
  "2019-05-05",                 9.0, "c",
  "2019-10-04",                    8.0, "c",
  "2020-06-05",                 9.1, "c",
  "2020-09-11",                    9.0, "c",
  "2021-04-23",                    9.0, "c",
  "2022-05-08",                 9.6, "c") %>% 
  mutate(SAMPLE_DATE = ymd(SAMPLE_DATE))

ggplotly(
  ggplot(df3, aes(SAMPLE_DATE, REPORT_RESULT_VALUE, colour = CHEMICAL_NAME)) +
    geom_line() +
    geom_point() +
    scale_y_continuous(trans = scales::pseudo_log_trans(sigma = 0.1),
                       breaks = scales::breaks_pretty(n = 10)) +
    labs(x = 'Sample date', y = "Concentration (mg/L)")
  )

Here ideally I would like to have the labels spread out more.


Solution

  • Here's a way to do it in ggplot2 using the handy scales::pseudo_log_trans function and then using plotly::ggplotly to convert to plotly. pseudo_log_trans is handy when you want a (mostly) log scale but you want to accommodate zeroes or even negative values.

    ggplotly(
      ggplot(df2, aes(SAMPLE_DATE, REPORT_RESULT_VALUE)) +
      geom_line() +
      geom_point() +
      scale_y_continuous(trans = scales::pseudo_log_trans(sigma = 0.005),
                         breaks = scales::breaks_pretty(n=10),  # EDIT
                         labels = scales::number_format()) + 
      labs(x = 'Sample date', y = "Concentration (mg/L)")
    

    enter image description here )