Save plot as SVG removing stroke on filled symbols - r

I have been using filled symbols in ggplot2 and never had any problems exporting to png. However, when I export to svg, for some shapes (triangles and diamonds) one side of the symbol has no stroke.
This initially occurred when I was plotting some maps, so I have tried to replicate the issue with just simple example plots - it's still happening. I can't fathom what is causing one side of the symbols to disappear like this. Is this something I am failing to specify when exporting as svg? Or is there a bug somewhere? Any help would be much appreciated.
Here's an example:
And the code that created this image:
library(tidyverse)
plot =
data_frame(x = 1:5, y = 1:5, group = c("tri", "sq", "tri", "sq", "dia")) %>%
ggplot(aes(x,y, shape = group)) +
geom_point(fill = "red", colour = "black", size = 4) +
scale_shape_manual(values = c(23,22,24)) +
theme_bw()
plot %>% ggsave("test.svg", ., height = 10, width = 10, units = "cm")
Note: I have tried using svglite() directly to export - same thing happens.

This seems like a bug in svglite:
Missing edges in svg file for some point characters when background color is set
First reported on ggplot2 github:
ggsave missing edges with some shapes in svg format

Related

Wiggling lines when animating ggplot choropleth with gganimate

I have a problem when using gganimate to animate a choropleth map made with ggplot2.
A selection of my data is available here and the code is:
library(tidyverse)
library(gganimate)
part_data <- readRDS(file = "part_data.Rds")
p <- part_data %>%
ggplot(aes(x = long, y = lat, group = group)) +
geom_polygon(aes(fill = confirmed), color = "grey70", size = 0.05) +
coord_map() +
scale_fill_distiller(trans = "log10", direction = 1, palette = "YlOrRd", na.value = "white") +
transition_time(time = date)
animate(p,
fps = 3,
duration = 5,
renderer = gifski_renderer("countyevolution.gif"),
width = 1200, height = 750, res = 100)
which yields this GIF:
Perhaps it's difficult to see but if you look closely you'll see that the borders between the counties are wiggling. This does not happen when I use transition_manual without transitions between the dates, so it must come from these transitions. But why?
Is it possible to somehow tell gganimate to keep the borders the same and only render the fill for each frame? Or can I somehow else make the border less obvious? I tried decreasing the size, but that does not seem to make a difference. Also, the borders seem a bit jagged.
This also happened to em recently: animated plots that contain maps or other static elements become wiggly or blink. I realized the wiggle happens because gganimate is also animating the map lines in each step of the animation. This explains why using other transition modes or removing transition animations solve the blinking.
As stated in this question, to exclude a ggplot layer from being animated you need to add a data argument. This way, the map or plot in the background will remain static, and the rest of the plot will animate.

Dynamically align plots (custom ggplot2 legend for spatial maps) in R

I have a number of maps that I'm generating in R using the sf library and I would like to have a nice looking legend. Unfortunately, it seems that the standard legend for geom_sf() are these ugly looking boxes. The only SO post I could find on adjusting shapes in ggplot2 legends is here.
The here is to use guides(colour = guide_legend(override.aes = list(shape = 16))); however, this only seems to work for geom_point() and not for geom_sf().
Unless someone can suggest an alternative method for changing the shape of legend objects I will need to design a custom legend in Inkscape and align this along with various maps.
Here's a snippet of the code to show what I've tried already:
legend <- image_read_svg('https://svgshare.com/i/FDV.svg')
p1 <- ggplot() +
geom_sf(data=otherroads, size = .45, aes(color=SUFTYPABRV)) +
geom_sf(data=allroads, size = .55, aes(color=SUFTYPABRV)) +
scale_color_manual(values = plotcolors, guide = "legend") + theme_map() +
labs(title = "Sydney")
ggdraw() +
draw_plot(p1) +
draw_image(legend, width = 0.4, hjust = -0.75, vjust = 0.43)
Good legend location example
The output looks good in this case; however, this won't work for me because it requires manual tweaking for every plot.
What I would like is for the location of this legend to be dynamically placed according to the ggplot object, which depends upon the city I'm plotting.
Bad legend location example
The code (and data) in it's entirety can be cloned from github: https://github.com/moldach/map-help.git
This answer is not to adress the legend placement, but changing the legend icons. From your examples, I gather your data produces a legend that looks like this by default:
# example from the geom_sf help page
nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
# throwing in some random categorical data
nc$catvar <- sample(LETTERS[1:5], nrow(nc), replace = TRUE)
ggplot(nc) +
geom_sf(aes(colour = catvar))
Not too long ago, ggplot added the ability to set what legend shape you wanted by implicitly (via the ellipsis) adding the key_glyph argument to all layers, such as geoms and stats.
ggplot(nc) +
geom_sf(aes(colour = catvar), key_glyph = "timeseries")
You could use this, to set the glyph to points and then use the override.aes trick to get the shapes that you want.
ggplot(nc) +
geom_sf(aes(colour = catvar), key_glyph = "point") +
guides(colour = guide_legend(override.aes = list(size = 3, shape = c(15:19))))
It should work with all the regular legend placement tools that are already in ggplot. You might have to specify locations specific for the plot, but at least you won't have to export your legend to svg files first before adding them.

How to specify a single colour for rasters with tmap?

I would like to adjust the basic colour of a raster plotted with tmap, when there is only one value in the raster.
Here is a very simple reproducible example:
library(raster)
library(tmap)
a <- raster(matrix(sample(c(1, NA), 10000, replace = TRUE, prob = c(0.01, 0.99)), nr = 100, nc = 100, ))
tm_shape(a) +
tm_raster()
You can see that the default yellow colour is barely visible by a human eye. Hence, when drawing a map where you only have a few pixels, it is extremely difficult to locate where are the pixels with values.
Unfortunately, I was not able to change this colour after multiple attempts. I think this issue may be encountered by other users, thus if a simple answer arises here it might be very helpful.
Unsuccessful attempts:
tm_shape(a) +
tm_raster(col = "black")
tm_shape(a) +
tm_raster(palette = "RdBu")
Note: for this one, I expected either a Red or a Blue colour to show up. Not grey... I tried to adjust midpoints as well but nothing changed.
tm_shape(a) +
tm_raster() +
tm_layout(aes.color= c(fill = "black"))
Apparently, when you just specifiy col= it colors the whole raster in one color. So I guess you have to chose the layer where the points are on? And then provide a argument to palette= as explained in the documentation.
This is how I got it to work:
tm_shape(a) +
tm_raster(col = "layer", palette = "black")

Extra spaces on labels including cyrillic symbols in ggplot2

I'm trying to make a simple plot in R using ggplot2. The data is stored in a dataframe with its column written in Russian. The problem is that the contents of the label is shifted from the right border of the latter. These extra spaces appeared whether the label names are defined explicitly (the code below) or implicitly from the dataframe column names.
ggplot(mtcars, aes(x = drat, y =mpg, color = cyl))+
geom_point() +
labs(color = "Русское название") +
theme(legend.background = element_rect(color = "black", linetype = "solid", size = 0.7),
legend.justification = c(1, 1),
legend.position = c(1, 1),
legend.title.align = 0)
The plot with the English title is depicted appropriately.
The encoding of the operational system is set as follows:
"LC_COLLATE=Russian_Russia.1251;LC_CTYPE=Russian_Russia.1251;LC_MONETARY=Russian_Russia.1251;LC_NUMERIC=C;LC_TIME=Russian_Russia.1251"
Is there a way to cope this problem?
I have faced the same issue when needed legend with cyrillic symbols. Looks like it is known issue reported in ggplot2 repo because of the default graphic device on Windows. Actually, if you would try to save your ggplot with ggsave, probably you won't get that issue.
I have not tried to save files by myself yet, but I have followed the reported issue and found some workaround specific for R studio here and it has worked for me, maybe it can solve your issue too. Sample code to run before plotting anything is:
trace(grDevices:::png, quote({
if (missing(type) && missing(antialias)) {
type <- "cairo-png"
antialias <- "subpixel"
}
}), print = FALSE)

Plotting a Tree Map in R using treemapify

Im making a treemap of some data using a pretty cool library called treemapifyof which the details can be found here and github repository here
Based on my reading of the documentation it seems to be based on ggplot2 so it should be possible to modify the graph using the grammar of graphics
My code is below with some made up data. The end result is pretty nice but i want to change the color scheme to a more subtle using the line scale_colour_brewer. The graph runs fine but the colour scheme seems to be ignored. Has anyone had any experience with this?
# Create Random Data
country <- c("Ireland","England","France","Germany","USA","Spain")
job <- c("IT","SOCIAL","Project Manager","Director","Vice-President")
mydf <- data.frame(countries = sample(country,100,replace = TRUE),
career = sample(job,100,replace=TRUE),
participent = sample(1:100, replace = TRUE)
)
# Set Up the coords
treemap_coords <- treemapify(mydf,
area="participent",
fill="countries",
label="career",
group="countries")
# Plot the results using the Green Pallete
ggplotify(treemap_coords,
group.label.size.factor = 2,
group.label.colour = "white",
label.colour = "black",
label.size.factor = 1) +
labs(title="Work Breakdown") +
scale_colour_brewer(palette = "Greens")
If you want to change the fill color of the rectangles, try the scale for fill instead the one for colour:
scale_fill_brewer(palette = "Greens")

Resources