Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linewidth not removing borders in geom_sf() #5333

Closed
emuise opened this issue Jun 22, 2023 · 8 comments
Closed

Linewidth not removing borders in geom_sf() #5333

emuise opened this issue Jun 22, 2023 · 8 comments

Comments

@emuise
Copy link

emuise commented Jun 22, 2023


I found a problem with ggplot2 when trying to remove the borders of a polygon using geom_sf() after the change from the size argument to the linewidth argument. I am on ggplot 3.4.2

I expected setting linewidth = 0 to remove the borders, as it previously did when setting size = 0.

Here is the code to reproduce the bug:

library(sf)
library(tidyverse)
library(patchwork)

nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
p1 <- ggplot(nc) +
  geom_sf(linewidth = 0) +
  ggtitle("linewidth = 0 w/o fill")

p2 <- ggplot(nc) +
  geom_sf(aes(fill = NAME), linewidth = 0) + 
  ggtitle("linewidth = 0 w/ fill") +
  theme(legend.position = "none")

p1/p2
@teunbrand
Copy link
Collaborator

Thanks for the report! I can reproduce this, but only when using the windows device. Have you tried other devices, like {ragg} or the Cairo PNG device?

@thomasp85
Copy link
Member

This is not a bug as such. The R documentation for graphic devices says that graphic devices should be implemented in such a way that a line width of 0 should draw the thinnest possible line. Does that make sense? Maybe not, but it is the expected behaviour. It is much better to rely on setting the color to NA to turn off rendering

@emuise
Copy link
Author

emuise commented Jun 23, 2023

This is not a bug as such. The R documentation for graphic devices says that graphic devices should be implemented in such a way that a line width of 0 should draw the thinnest possible line. Does that make sense? Maybe not, but it is the expected behaviour. It is much better to rely on setting the color to NA to turn off rendering

Hi Thomas, this does appear to work within the RStudio viewer, but when I use ggsave(), there still appears to be lines between the polygons (albeit small ones).

Reprex:
`
library(sf)
library(tidyverse)
library(patchwork)

nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)

p1 <- ggplot(nc) +
geom_sf(col = NA) +
ggtitle("col = NA w/o fill")

p2 <- ggplot(nc) +
geom_sf(aes(fill = NAME), col = NA) +
ggtitle("col = NA w/ fill") +
theme(legend.position = "none")

ggsave(here::here("outputs", "test_nc.png"), p1/p2, height = 6, width = 6)
`
test_nc

@emuise emuise closed this as completed Jun 23, 2023
@emuise
Copy link
Author

emuise commented Jun 23, 2023

Accidentally closed, see previous comment (sorry).

@emuise
Copy link
Author

emuise commented Jun 23, 2023

Thanks for the report! I can reproduce this, but only when using the windows device. Have you tried other devices, like {ragg} or the Cairo PNG device?

Following Thomas' suggestion, I switched to col = NA and also tried using {ragg}. Reprex still contains lines around polygons.

library(sf)
library(tidyverse)
library(patchwork)

nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)

p1 <- ggplot(nc) +
  geom_sf(col = NA) +
  ggtitle("col = NA w/o fill")

p2 <- ggplot(nc) +
  geom_sf(aes(fill = NAME), col = NA) + 
  ggtitle("col = NA w/ fill") +
  theme(legend.position = "none")


ggsave(here::here("outputs", "test_nc.png"), p1/p2, height = 6, width = 6,
       device = ragg::agg_png)

test_nc

@teunbrand
Copy link
Collaborator

Aside from some anti-aliasing in the second plot. which probably is difficult to get around, I'm having some trouble seeing what borders remain in the first plot.

@emuise
Copy link
Author

emuise commented Jun 23, 2023

@teunbrand the first plot works as I'd like it to. I agree it could be anti-aliasing in the second plot, however, I have made plots in the past (prior to the size -> linewidth change) that did not have this issue. The major issue I have with the second plot is when I try to plot polygons in black (especially a complex polygon), the outlines show up. The only workaround I've found is to set the colour of each polygon to the same as the fill, and reduce linewidth as much as possible. But it seems like there should be an easier way to remove the borders.

@teunbrand
Copy link
Collaborator

Thanks that clarifies things: I do see border artefacts in some devices when setting the fill to black. Sadly though, I don't think there is an opportunity for ggplot2 to change anything, as ggplot2 mostly passes shapes to grid, and grid passes shapes to the graphics device. If there is an issue with the graphics device, it is at least one step removed from ggplot2's control.

As a workaround, I'd suggest to use ggsave(..., device = png, type = "cairo") when you need fills that aren't anti-aliased. Of course, your suggestion to match the colour to the fill also works. If order to avoid having to use two fully defined scales, you can use aes(fill = ..., colour = after_scale(fill)) to copy over the fill colour.

lambdamoses added a commit to pachterlab/voyager that referenced this issue Sep 20, 2023
…inewidth = 0 on Windows. Closing #13. Version bumped to make this change visible to Bioconductor users. I thought I was done with bugs for now when I version bumped earlier today, but I was wrong.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants