I'm making icons with ggimage from an svg :
in.svg:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
x="0px"
y="0px"
viewBox="0 0 100 100"
xml:space="preserve"
style="enable-background:new 0 0 100 100;"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" /><path
d="m 56.215759,24.245239 2.723511,-3.026123 c 1.063416,0.750855 2.304382,1.141236 3.553894,1.141236 1.583008,0 3.165039,-0.602539 4.370117,-1.807618 2.40918,-2.410156 2.40918,-6.332031 0,-8.742187 -2.410156,-2.4101562 -6.330078,-2.4101562 -8.740234,0 -2.179199,2.179199 -2.367798,5.583618 -0.606201,7.999634 l -3.096131,3.440246 c -46.999406,-0.760793 24.296811,25.305901 1.795044,0.994812 z m 3.32135,-11.02063 c 0.81543,-0.814453 1.885743,-1.222656 2.956055,-1.222656 1.070313,0 2.140625,0.408203 2.956055,1.222656 1.628906,1.63086 1.629883,4.283203 0,5.914063 -1.63086,1.628906 -4.28125,1.628906 -5.91211,0 -1.630859,-1.63086 -1.630859,-4.283203 0,-5.914063 z" /></svg>
Data and plot to make the icons
# https://stackoverflow.com/questions/6862742/draw-a-circle-with-ggplot2
gg_circle <- function(r, xc, yc, color="black", fill=NA, ...) {
x <- xc + r*cos(seq(0, pi, length.out=100))
ymax <- yc + r*sin(seq(0, pi, length.out=100))
ymin <- yc + r*sin(seq(0, -pi, length.out=100))
annotate("ribbon", x=x, ymin=ymin, ymax=ymax, color=color, fill=fill, ...)
}
df = data.frame(x = c(0,1), y = c(0,1))
df2 = data.frame(x = c(0.5), y = c(.5))
image = "in.svg"
ggincon = ggplot(df,
aes(x=x, y=y)) +
gg_circle(r=0.05, xc=0.5, yc=0.5, color=NA,
fill='#F4F44F',
alpha=1) +
ggimage::geom_image(data = df2,
mapping = aes(x,y,image = image),
colour = '#FA434F',
size = .7) +
coord_fixed() +
theme_void();ggincon
But as you can see, it is pixelated
So I resize the svg :
magick in.svg -resize 1200x1200 -gravity center out.svg
image = "out.svg"
And rerun the code :
But now the 'resolution' is fine but the resize command changed the 'smoothness' of the curved lines... as in resizing SVG makes it jagged and not smooth with magick.
How could I make the SVG correctly be imported and placed on the color circle without pixelating it or changing the actual shapes (i.e., circles should stay circles)?
The problem is that ggimage::geom_image
returns a grid::rasterGrob
, which in its own words draws "a bitmap image" (i.e. not a vector image).
An alternative solution exists in svgparser
, which keeps its input as a native vector image.
im_svg <- svgparser::read_svg(image, style_default=list(fill="#FA434F"))
ggicon <- ggplot2::ggplot(df, ggplot2::aes(x=x, y=y)) +
gg_circle(r=0.05, xc=0.5, yc=0.5, color=NA, fill="#F4F44F", alpha=1) +
ggplot2::annotation_custom(im_svg) +
ggplot2::coord_fixed() +
ggplot2::theme_void()
svglite::svglite("ggicon.svg")
print(ggicon)
dev.off()
Be sure when drawing/saving this file to use an actual SVG device, such as svglite
. (StackOverflow won't let me upload an .svg image to accurately show the result)