Search code examples
rggplot2scalegeom-baryaxis

second y-axis with other scale


I created a barchart with ggplot2 geom_bar and want to have two metrics in the bars. I used melt to do so. However, I now need a second y-axis with another scale, because the numbers of the two metrics are too different.

In the following the dataframe and the code I used:

df <- data.frame(categories = c("politics", "local", "economy", "cultural events", 
                                "politics", "local", "economy", "cultural events"), 
               metric = c("page", "page", "page", "page", 
                          "product", "product", "product", "product"), 
               value = c(100L, 50L, 20L, 19L, 
                         950000L, 470000L, 50000L, 1320L))

In the following the code I used to create the plot and the second y-axis:

x <- ggplot(df, aes(x=categories, y=value, fill = metric))
x + geom_bar(stat = "identity", position = "dodge") +
  scale_y_continuous(sec.axis=sec_axis(~. *1000), limits=c(1,1000))

However, now no bars appear in the chart anymore... Does anybody know how to solve this problem?


Solution

  • Another approach could be to use highcharter

    library(dplyr)
    library(tidyr)
    library(highcharter)
    
    #convert your data in wide format
    df <- df %>% spread(metric, value)
    
    #plot
    highchart() %>% 
      hc_xAxis(categories = df$categories) %>%
      hc_yAxis_multiples(
        list(lineWidth = 3, title = list(text = "Page")),
        list(opposite = TRUE, title = list(text = "Product"))
      ) %>% 
      hc_add_series(type = "column", data = df$page) %>% 
      hc_add_series(type = "line", data = df$product, yAxis=1) # replace "line" with "column" to have it in bar format
    

    Output plot is:

    enter image description here

    Sample data:

    df <- structure(list(categories = structure(c(4L, 3L, 2L, 1L, 4L, 3L, 
    2L, 1L), .Label = c("cultural events", "economy", "local", "politics"
    ), class = "factor"), metric = structure(c(1L, 1L, 1L, 1L, 2L, 
    2L, 2L, 2L), .Label = c("page", "product"), class = "factor"), 
        value = c(100L, 50L, 20L, 19L, 950000L, 470000L, 50000L, 
        1320L)), .Names = c("categories", "metric", "value"), row.names = c(NA, 
    -8L), class = "data.frame")