rvisualizationr-highcharter

Create inverted dumbbell plot in r with Highcharter


I am trying to create a dumbbell plot using the highcharter package. Since the Highcharts type dumbbell only works with two observations, I have been using columnrange and scatter together to create it. I can get it to work vertically, but I am unable to rotate it so that the lines are horizontal.

I have tried adding inverted to the hchart() function and to the hc_plotOptions() but neither appears to work properly. Here is my code:

# create the data set
df <- data.frame(
  mean = c(-0.55, 1.73, 1.18, -0.28, -0.61, 
           0.01, 0.98,  0.41, 0.64, -0.87,
           -0.28, 1.43, -0.15, 1.19, -0.8, 
           -0.63, 0.12, -0.07, 0.06, 0.56),
  group = c("Group 1", "Group 2", "Group 3", "Group 4", "Group 5",
            "Group 1", "Group 2", "Group 3", "Group 4", "Group 5",
            "Group 1", "Group 2", "Group 3", "Group 4", "Group 5",
            "Group 1", "Group 2", "Group 3", "Group 4", "Group 5"),
  class = c("Class 1", "Class 1","Class 1", "Class 1", "Class 1",
            "Class 2", "Class 2","Class 2", "Class 2", "Class 2",
            "Class 3", "Class 3","Class 3", "Class 3", "Class 3",
            "Class 4", "Class 4","Class 4", "Class 4", "Class 4"),
  min = c(-0.62, 0.09, -0.14, -0.28, -0.85,
          -0.62, 0.09, -0.14, -0.28, -0.85,
          -0.62, 0.09, -0.14, -0.28, -0.85,
          -0.62, 0.09, -0.14, -0.28, -0.85),
  max = c(0.01, 1.74, 1.17, 1.19, 0.54,
          0.01, 1.74, 1.17, 1.19, 0.54,
          0.01, 1.74, 1.17, 1.19, 0.54,
          0.01, 1.74, 1.17, 1.19, 0.54)
)

df %>% 
  # add the column range to serve as the dumbbell plot
  hchart(
    type = "columnrange",
    hcaes(x = group, y = mean, low = min, high = max),
    # remove from legend
    showInLegend = FALSE
  ) %>% 
  # add the dots
  hc_add_series(
    data = df,
    "scatter",
    hcaes(x = group, y = mean, group = class)
  ) %>%
  # adjust the look
  hc_plotOptions(
    series = list(
      # make everything inverted (DOESN'T DO ANYTHING)
      inverted = TRUE
    ),
    # adjust appearance of column ranges
    columnrange = list(
      # make it look narrower
      maxPointWidth = 6,
      # make it black
      color = "black"
    ),
    scatter = list(
      # remove the linewidth so there is no linewidth
      lineWidth = 0,
      # adjust the points
      marker = list(
        # make the size of the circles bigger
        radius = 9
      ),
      showInLegend = TRUE
    )
  ) %>% 
  hc_yAxis(
    title = list(
      text = "Score Relative to Overall Average<br>(In Standard Deviations)",
      style = list(
        fontFamily = "Roboto",
        fontSize = "20px"
      ),
      useHTML = TRUE,
      textAlign = "center"
    ),
    #categories = c(-0.5, 0, 0.5, 1),
    plotLines = list(
      # add a solid black line at y = 0
      list(
        color = "black",
        width = 2,
        value = 0
      )
    )
  ) %>% 
  hc_xAxis(
    title = NULL
  ) %>% 
  hc_title(
    text = "This is my title",
    style = list(
      fontFamily = "Roboto",
      fontSize = "24px"
    )
  ) 

This what I end up getting:

vertical dumbbell plot

And this is a plot I made with ggplot2 that looks more or less how I would like the Highcharts version to appear.

horizontal dumbbel


Solution

  • Your code is 99% of the way there - you just have to remove inverted=TRUE from hc_plotOptions() and instead add a pipe to the hc_chart() function instead, which does take the argument inverted=TRUE.

    df %>% 
      # add the column range to serve as the dumbbell plot
      hchart(
        type = "columnrange",
        hcaes(x = group, y = mean, low = min, high = max),
        # remove from legend
        showInLegend = FALSE
      ) %>% 
      # add the dots
      hc_add_series(
        data = df,
        "scatter",
        hcaes(x = group, y = mean, group = class)
      ) %>%
      # adjust the look
      hc_plotOptions(
        # adjust appearance of column ranges
        columnrange = list(
          # make it look narrower
          maxPointWidth = 6,
          # make it black
          color = "black"
        ),
        scatter = list(
          # remove the linewidth so there is no linewidth
          lineWidth = 0,
          # adjust the points
          marker = list(
            # make the size of the circles bigger
            radius = 9
          ),
          showInLegend = TRUE
        )
      ) %>% 
      hc_yAxis(
        title = list(
          text = "Score Relative to Overall Average<br>(In Standard Deviations)",
          style = list(
            fontFamily = "Roboto",
            fontSize = "20px"
          ),
          useHTML = TRUE,
          textAlign = "center"
        ),
        #categories = c(-0.5, 0, 0.5, 1),
        plotLines = list(
          # add a solid black line at y = 0
          list(
            color = "black",
            width = 2,
            value = 0
          )
        )
      ) %>% 
      hc_xAxis(
        title = NULL
      ) %>% 
      hc_title(
        text = "This is my title",
        style = list(
          fontFamily = "Roboto",
          fontSize = "24px"
        )
      ) %>%
      hc_chart(
        inverted = TRUE
      )
    

    Which then results in: Inverted dumbbell plot in highcharter