Home > front end >  Having trouble creating a stacked bar chart
Having trouble creating a stacked bar chart

Time:07-07

I'm a total newbie to R. I'm trying to create a stacked bar chart based on this code:

activity <- c("mean_fairly_active", "mean_fairly_active", "mean_fairly_active",
              "mean_fairly_active", "mean_fairly_active", "mean_fairly_active",
              "mean_fairly_active", "mean_lightly_active", "mean_lightly_active",
              "mean_lightly_active", "mean_lightly_active", "mean_lightly_active",
              "mean_lightly_active", "mean_lightly_active", "mean_very_active",
              "mean_very_active", "mean_very_active", "mean_very_active",
              "mean_very_active", "mean_very_active", "mean_very_active",
              "mean_sedentary", "mean_sedentary", "mean_sedentary", 
              "mean_sedentary", "mean_sedentary", "mean_sedentary",
              "mean_sedentary")
minutes <- c("14.3", "13.1", "12.0", "12.1", "15.2", "14.5", "14.0", "197", "190",
             "185", "204", "207", "174", "192", "23.0", "20.8", "19.4", "20.1", 
             "21.9", "20.0", "23.1", "1007", "989", "962", "1000", "964", "990", 
             "1028")
weekday <- c("Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun", "Mon", 
             "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun", "Mon", "Tues", "Wed",
             "Thurs", "Fri", "Sat", "Sun", "Mon", "Tues", "Wed", "Thurs", "Fri",
             "Sat")
merged_means <- data.frame (activity, minutes, weekday)
print(merged_means)

The ggplot I'm running:

ggplot(merged_means, aes(x=weekday, y=minutes, fill=activity))  
  geom_bar(stat = "identity")

The resulting graph shows all the numbers of the y-axis squished on the bottom half of the graph, the days in the wrong chronological order (Fri, Mon, Sat, Sun, etc), and the fill colors in the wrong amounts. Any help is appreciated!

CodePudding user response:

You have a few issues to address:

  1. You need to convert minutes to numeric, since it is currently a character vector, and R doesn't know you intend these character strings to be interpreted as numbers.
  2. The weekdays are converted to a factor variable inside ggplot, and will therefore be arranged in alphabetical order. To prevent this, make weekday a factor variable with your chosen ordering.
  3. Writing geom_bar(stat = "identity") is just a long way of writing geom_col()
  4. For plotting purposes, it's a good idea to present your legend labels without distracting underscores, and to add appropriate axis titles.
  5. With clearly ordered factor levels like the activity scale, you should also make them a factor with the correct ordering.
  6. The default styling can be adjusted to taste, and in particular, it would be sensible for this data set to use a sequential palette to emphasise the activity level.

Putting all these together we might have something like this:

ggplot(merged_means, 
       aes(x    = factor(weekday, unique(weekday)), 
           y    = as.numeric(minutes), 
           fill = factor(trimws(gsub("mean|_", " ", activity)),
                         c("very active",
                           "fairly active",
                           "lightly active",
                           "sedentary"))))  
  geom_col(color = "gray50")  
  scale_fill_brewer(palette = "YlOrRd", direction = -1)  
  labs(x = "Weekday", y = "Minutes", fill = "Activity")  
  theme_minimal(base_size = 16)

enter image description here

  • Related