tidyverse / ggplot2

An implementation of the Grammar of Graphics in R
https://ggplot2.tidyverse.org
Other
6.49k stars 2.02k forks source link

White-line artifacts with `geom_col` #4183

Closed Kodiologist closed 4 years ago

Kodiologist commented 4 years ago

(Originally posted on Stack Overflow, but I suspect it's a bug.)

I'm not sure exactly what conditions cause this to happen, but here's a pretty small example derived from the real plot that I was working on when I ran into this:

library(ggplot2)

d = data.frame(x = seq(0, 2, len = 2500))
d$y = d$x^2

ggsave("~/plot.png", width = 3, height = 4, dpi = 90,
    ggplot(d) +
    geom_col(aes(x, y), width = max(diff(d$x))) +
    theme_bw() +
    theme(
        panel.border = element_blank(),
        panel.grid = element_blank(),
        axis.text.y = element_blank(),
        axis.ticks.y = element_blank()))

With ggplot2 3.3.2 on R 3.6.2 on Linux, I get this:

Output of the code above

Note the white line at about x = 0.8.

Presuming that this won't be fixed soon, I'd still appreciate a reliable workaround.

clauswilke commented 4 years ago

It's almost certainly an aliasing artifact. The workaround is to not draw a filled area by drawing many thin vertical lines.

Kodiologist commented 4 years ago

I don't understand. There may well be a way to get something that looks like the plot above without geom_col, but in the real plot, the aes of the geom_col has a fill setting. I don't think there's any other way to get something like the below, so what should I do? plot

clauswilke commented 4 years ago

The simple answer is it's very difficult to avoid aliasing effects for such plots. Once grid graphics support gradients, this may be possible, but at this time it is not.

The geom geom_ridgeline_gradient() from ggridges provides a geom that allows you to map color along the x axis, but it can also create aliasing artifacts and actually provides a fudge factor parameter to minimize the effect. You may also have to use a different graphics device, or increase the resolution of your graphics device.

library(ggplot2)
library(ggridges)

d = data.frame(x = seq(0, 2, len = 2500))
d$y = d$x^2

# default creates aliasing artifacts in this case
ggplot(d) +
  geom_ridgeline_gradient(aes(x, y = 0, height = y, fill = y)) +
  theme_bw() +
  theme(
    panel.border = element_blank(),
    panel.grid = element_blank(),
    axis.text.y = element_blank(),
    axis.ticks.y = element_blank()
  )

# increasing `gradient_lwd` to 1 helps
ggplot(d) +
  geom_ridgeline_gradient(aes(x, y = 0, height = y, fill = y), gradient_lwd = 1) +
  theme_bw() +
  theme(
    panel.border = element_blank(),
    panel.grid = element_blank(),
    axis.text.y = element_blank(),
    axis.ticks.y = element_blank()
  )

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

Kodiologist commented 4 years ago

Thanks for the detailed explanation. I'll try out geom_ridgeline_gradient.

rfaelens commented 1 year ago

The ragg graphics library fixed this issue for me.