Looking for some help ironing out ggflags issues

ggplot2

#1

Hi everyone, I’m working on some features for my ggflags fork (although I don’t know whether @baptiste is interested in a PR, because I haven’t asked them yet!) , and I was hoping to canvas some help on a few issues I’m having.

Problem #1: size scaling

My understanding is that scale_size scales area, not radius. That makes sense when I inspect the size values being passed to my makeContent function: if I provide scale_size(range = c(0, 20)) to a plot, my points come out like:

Size df column     Size given to geom
1                                 0.0
1.25                             10.0
1.5                              14.14
1.75                             17.32
2                                20

But my makeContent methods draws the geom using width = x$size[ii] * unit(1, "mm") and height = x$size[ii] * unit(1, "mm"). I’m guessing this means that I’m essentially scaling twice, which is obviously not what I want. Should I just sqrt() these figures?

Problem #2: flag strokes not scaling with flags properly

I’ve added strokes to the flags by essentially plotting a point geom with shape 21 over the top:

grobTree(
          grImport2::pictureGrob(
            picture = .flaglist[[x$country[[ii]]]],
            x = x$x[ii], y = x$y[ii],
            width = x$size[ii] * unit(1, "mm"),
            height = x$size[ii] * unit(1, "mm"),
            distort = FALSE),
          pointsGrob(
            x = x$x[ii], y = x$y[ii], pch = 21,
            gp = gpar(
              fill = 0, col = x$colour[ii],
              fontsize =
                (x$size[ii] * .pt) + (x$stroke[ii] * .stroke),
              lwd = x$stroke[ii] * .stroke / 2)))

The strokes aren’t out by a fixed amount: at some flag sizes they’re too big, and at large font sizes they’re too small. I’m kind of guessing this by going on how geom_point is plotted, but I don’t really understand it well enough to get it right. I feel it would be more intuitive for fontsize to use the same calculation as the flag width and height and then convert to fontsize units using convertUnits. Are those units points?

Problem #3: flags (but not outlines) spilling over plotting area

In most cases, the flags keep rendering over the plotting edges:

df = data_frame(x = 1:3, y = 1:3, country = c('au', 'de', 'us'))
ggplot(df) + geom_flag(aes(x = x, y = y, country = country), size = 50, stroke = 2)

This also occurs when using ggsave (with raster or PDF output) or when using base R devices (png or pdf, plot, dev.off), but it doesn’t happen when using grid.export to save to SVG (it correctly clips them to the plotting area then).

If anyone can shed some light on these problems, it’d be greatly appreciated!


#2

I wish I could help more with this, but the unfortunately reality is that takes me a day or two to load ggplot2 up into my brain so I don’t currently remember how it works.

I’d start by looking at the implementation of geom_point - that should hopefully help you to position the stroke correctly and what the units mean.

I’m not sure why you’re having the clipping problem - it looks like the strokes are clipped correctly, so it’s possible a bug in grid. You might want to email Paul Murrell with a small reprex.


#3

Your brain need defragmentation! :smile:


#4

I’ve often thought it might be useful to have a minimal ggdummy package with only the bare-bones components of ggplot2, to test new features, and, just as importantly, understand how it all fits together. Just one or two simple geoms (point and line), identity stat, few scales, cartesian coords.

Understanding the package’s internals has always been somewhat overwhelming (proto, then ggproto, but also sheer size and complexity, as well as undocumented breaking changes after updates); it’s definitely a barrier for developing extensions. Having a minimal, well-documented testbed, would make it so much easier to develop new features.

@rensa Please feel free to take over the ggflags package; you seem to be very motivated, whereas I only wrote it as a proof-of-principle / toy example and I wouldn’t have time to maintain it or extend it.


#5

That’s okay, @hadley! Paul’s actually been lending me a lot of help as I work this out; he just suggested that I use circleGrob instead of pointsGrob (plotting it behind the flag, of course), and I’m finding that a lot easier to convert the units with. Still not quite there with the sizing, but getting there :slight_smile:

Thanks, @baptiste! I have a few other ideas I’d like to try out once I finish the project that started this (eg. alternate flag sets, maybe a package for arbitrary SVG points), so I’ll keep working on it :smiley: