OxL
OxL

Reputation: 105

Horizontal white lines in ggplot bar graph

When I save a graph from R using ggplot2 and geom_col() or geom_bar(stat = 'identity') it comes out with some unsightly horizontal white lines.

Data looks like this:

> head(mouse_track_data)
session site BM.pile ox.pile       type  mice skinks geckos 
1 dec_2018    1       1    1.10 control FALSE   TRUE  FALSE            
2 dec_2018    1       2    1.12 design1 FALSE  FALSE  FALSE           
3 dec_2018    1       3    1.11 control FALSE  FALSE  FALSE            
4 dec_2018    1       4    1.80 control FALSE  FALSE  FALSE            
5 dec_2018    1       5    1.60 design1 FALSE  FALSE  FALSE            
6 dec_2018    1       6    1.50 control FALSE  FALSE  FALSE            

Here's my code:

ggplot(data = mouse_track_data, aes(x = session, y = as.numeric(mice), fill = type)) + 
  geom_bar(stat='identity') +
  theme_classic() +
  theme(text = element_text(size=15),
        axis.text.x = element_text(angle = 45, hjust = 1)) +
  xlab("Tracking session") +
  ylab("Number of tunnels with mouse tracks") +
  theme(axis.title.y = element_text(margin = margin(t = 0, r = 7, b = 0, l = 0))) +
  theme(axis.title.y = element_text(margin = margin(t = 0, r = 7, b = 0, l = 0)))  +
  theme(legend.title = element_blank(), legend.position = c(-2, -2)) +
  scale_fill_manual(values = c("control" = "#37a1c1", "design1" = "#9ce2cb", "design2" = "#445a9c"),
                    labels = c(" Control", " Single grade", " Mixed grade")) +
  scale_x_discrete(labels = c('Dec 2019', "April 2019", "Nov 2019", "March 2020")) +
  scale_y_continuous(breaks=seq(0, 50, 10), limits = c(0,52), expand = c(0,0)) +
  theme(axis.line = element_blank())

With this, or using geom_col(), when exporting as ESP or PDF, I get a figure that looks like this:

graph using EPS

With fine white lines going accross all the columns. I assume this is something to do with it counting each data point and then piling them up?

If I do the code with geom_bar() it doesn't have white lines but it doesn't show the data how I want it.

Upvotes: 8

Views: 4185

Answers (2)

filups21
filups21

Reputation: 1927

You can also just add the same variable to the color argument of aes. So your aes call becomes:

aes(x = session, y = as.numeric(mice), fill = type, color = type))

You also have to have the same fill & color scales, so add:

scale_color_manual(values = c("control" = "#37a1c1", "design1" = "#9ce2cb", "design2" = "#445a9c"), labels = c(" Control", " Single grade", " Mixed grade"))

ggplot2 uses the fill argument to fill columns/bars and the color argument to color the outline of the column/bar. When you don't specify an outline color, you can end up with white lines, like you observed. Specifying the same outline & fill colors avoids the issue you saw. Pre-aggregating, as Claus Wilke suggested, helps in some cases, but not always. If you have thousands of fill colors, for instance, you still end up with white lines, pre-aggregated or not.

Upvotes: 1

Claus Wilke
Claus Wilke

Reputation: 17820

When you use geom_col() you're getting one bar segment per data value, and that creates your white lines. The following example shows this in exaggerated manner.

library(tidyverse)

mtcars %>%
  mutate(cyl = factor(cyl), am = factor(am)) %>%
  ggplot(aes(x = cyl, y = 1, fill = am)) +
  geom_col(color = "white")

The easiest workaround is to manually aggregate, e.g. with group_by() and summarize():

mtcars %>%
  mutate(cyl = factor(cyl), am = factor(am)) %>%
  group_by(cyl, am) %>%
  summarize(count = n()) %>%
  ggplot(aes(x = cyl, y = count, fill = am)) +
  geom_col(color = "white")
#> `summarise()` regrouping output by 'cyl' (override with `.groups` argument)

Created on 2020-09-26 by the reprex package (v0.3.0)

Note: geom_col() is the same as geom_bar(stat = "identity").

Upvotes: 6

Related Questions