larmarange / ggstats

Extension to ggplot2 for plotting stats
https://larmarange.github.io/ggstats/
GNU General Public License v3.0
26 stars 1 forks source link

Feature request: option to make x-axis symmetric in gglikert() #66

Open ehickman0817 opened 1 week ago

ehickman0817 commented 1 week ago

I am using the gglikert() function from the ggstats package to create horizontal stacked bar charts centered on the neutral response. Liking it a lot more than the likert package! I would like to know how to manually set the x-axis limits to 100% on either side of 0%. Here is an example dataframe and code (please ignore factor ordering being incorrect!):

example_data <- data.frame(
            Pre = as.factor(c("Somewhat Familiar","Unfamiliar","Somewhat Familiar",
                              "Somewhat Unfamiliar","Somewhat Familiar","Unfamiliar",
                              "Neither Unfamiliar or Familiar","Unfamiliar",
                              "Neither Unfamiliar or Familiar","Unfamiliar")),
           Post = as.factor(c("Very Familiar",
                              "Very Familiar","Somewhat Familiar",
                              "Very Familiar","Very Familiar","Very Familiar",
                              "Very Familiar","Somewhat Familiar","Very Familiar",
                              "Somewhat Familiar"))
   )

gglikert(example_data,
         add_totals = FALSE)

ReproPlot1

Here, the function has set the axis limits based on the percentages within each of the groups. I would like the x-axis to go to 100% (as there are other questions with different data distributions and I would like all the axes to be the same, though the answers are slightly different, so I can't facet them). Is it possible for this to be added as a feature? (or, a workaround?) I searched documentation and stack overflow, and tried workarounds with ggplot2 (e.g. xlim), but wasn't successful in figuring this out! Thanks!

larmarange commented 1 week ago

You can simply adjust the axis with xlim() or scale_x_continuous(). Use label_percent_abs() to reproduce the labels on the axis.

library(ggstats)
library(ggplot2)

example_data <- data.frame(
  Pre = as.factor(c("Somewhat Familiar","Unfamiliar","Somewhat Familiar",
                    "Somewhat Unfamiliar","Somewhat Familiar","Unfamiliar",
                    "Neither Unfamiliar or Familiar","Unfamiliar",
                    "Neither Unfamiliar or Familiar","Unfamiliar")),
  Post = as.factor(c("Very Familiar",
                     "Very Familiar","Somewhat Familiar",
                     "Very Familiar","Very Familiar","Very Familiar",
                     "Very Familiar","Somewhat Familiar","Very Familiar",
                     "Somewhat Familiar"))
)

gglikert(example_data, add_totals = FALSE) +
  scale_x_continuous(
    limits = c(-1, 1),
    labels = label_percent_abs()
  )
#> Scale for x is already present.
#> Adding another scale for x, which will replace the existing scale.

Created on 2024-07-03 with reprex v2.1.0

larmarange commented 1 week ago

Following https://stackoverflow.com/a/62393903/7943547 you could also use symmetric_limits().

library(ggstats)
library(ggplot2)

example_data <- data.frame(
  Pre = as.factor(c("Somewhat Familiar","Unfamiliar","Somewhat Familiar",
                    "Somewhat Unfamiliar","Somewhat Familiar","Unfamiliar",
                    "Neither Unfamiliar or Familiar","Unfamiliar",
                    "Neither Unfamiliar or Familiar","Unfamiliar")),
  Post = as.factor(c("Very Familiar",
                     "Very Familiar","Somewhat Familiar",
                     "Very Familiar","Very Familiar","Very Familiar",
                     "Very Familiar","Somewhat Familiar","Very Familiar",
                     "Somewhat Familiar"))
)

symmetric_limits <- function (x) {
  max <- max(abs(x))
  c(-max, max)
}

gglikert(example_data) +
  scale_x_continuous(
    limits = symmetric_limits,
    labels = label_percent_abs()
  )
#> Scale for x is already present.
#> Adding another scale for x, which will replace the existing scale.

Created on 2024-07-03 with reprex v2.1.0

larmarange commented 1 week ago

I may consider an option to include symmetric axis.

ehickman0817 commented 1 week ago

Thank you so much, this worked (the first option, from stack overflow)!! I changed it to scale_x_continuous(labels = function(x) abs(x)*100, limits = c(-1, 1)) so that the values are positive (I don't care too much about the "%" part of the label, since I'll just add an x-axis title). Appreciate the quick response!