4

I have a map with polygons and points on it - showing countries of interest in the world.

I want legends for both items (points and polygons), but can't add them. The polygon is plotted first (and so has a legend), while the points do not appear on the legend. To try and address this i add

show.legend = T

However the legend then adds the dots on top of the polygon colors as below:

enter image description here

What i want is another legend item with a yellow dot, where i can set the label as i want.

At the moment i am generating the points layer using a separate file. Perhaps i need to do this all from one df with points and polygons included - to generate the points and polygons from a single aes. But i can't think how to do this given my points have no group number.

Here is my code as it stands:

world <- map_data("world")
countries <- read_excel("country_table.xlsx", sheet = 3) #table of coutries with interest

world3 <- merge(world, countries, all.x = TRUE) %>%
  arrange(order)

world4 <- world3 %>%
  filter(!is.na(interest))

city <- read_excel("country_table.xlsx", sheet = 4) #point data
city$long <- as.numeric(city$long)
city$lat <- as.numeric(city$lat)

ggplot() + 
  geom_polygon(data = world3, aes(x = long, y = lat, group = group),
               fill = "light grey") +
  geom_polygon(data = world4, aes(x = long, y = lat, group = group, fill = interest),
               col = "white") +
  scale_fill_manual(name = "Interest/Support:",
                    breaks = c("interest", "past", "current"),
                    values = c(interest = "#a7ef88", past = "#3a7f1d", current = "#1b5104"), 
                    labels = c("interest", "past", "current")) +
  theme_map() +
  theme(legend.position = "bottom") +
  coord_fixed(xlim = c(-130, 160),
              ylim = c(-50, 75), 
              ratio = 1.4) +
  geom_point(data = city, aes(x= long, y = lat),
             shape = 21, inherit.aes = F, size = 2, col = "black", fill = "yellow", show.legend = T)

Any thoughts?

aosmith
  • 34,856
  • 9
  • 84
  • 118
MorrisseyJ
  • 1,191
  • 12
  • 19
  • 2
    You'll need to move `fill` inside `aes()` for `geom_point()`. See examples of this (with different aesthetics) [here](https://stackoverflow.com/questions/35711592/r-legend-for-specific-points-in-ggplot) and [here](https://stackoverflow.com/questions/26756358/how-to-include-in-legend-symbol-of-mean-in-boxplot-with-ggplot). – aosmith Jul 16 '18 at 21:09
  • That partially works. Editing to geom_poin(...aes(..., fill = interest); and editing scale_fill_manual, to add: breaks(...,special), values(...special = "yellow"), labels(..."city"). Gives me a 4th item on the legend (a yellow box with a circle in it), but that circle remains in all the other boxes. What i want is a stand-alone circle. I can't seem to work this out from the other examples that you gave. – MorrisseyJ Jul 16 '18 at 21:42
  • Oh, good point. If you want a stand-alone legend you'll want to make use of an aesthetic that you haven't already used for making a legend. Maybe `color`? – aosmith Jul 16 '18 at 21:51
  • Thanks so much aosmith. I think i have this working - save for one small issue. Inside aes(), inside geom_point(), i set col = interest, and set fill = "yellow" outside the aes(). I then added scale_color_manual element to change the values = 'black". Now everything looks good except the scale_color_manual() legend item appears to the left of the scale_fill_manual() legend item (i would like it on the right, or, ideally, one above the other in the second example you gave above. Will post full code when i nail this down. – MorrisseyJ Jul 16 '18 at 23:09
  • You can control legend order in `guide()`. See [this answer](https://stackoverflow.com/questions/11393123/controlling-ggplot2-legend-display-order/11397958#11397958). You can use `legend.box` in `theme()` to make the two legends vertically stacked instead of horizontal. – aosmith Jul 17 '18 at 17:55
  • Perfect. Thanks so much. That is everything. Lots learnt. Final code posted as answer below. – MorrisseyJ Jul 17 '18 at 23:25

1 Answers1

2

Final code for the ggplot section posted below. Thanks to aosmith.

ggplot() + 
  #create base plot all polygons in grey
  geom_polygon(data = world3, aes(x = long, y = lat, group = group),
               fill = "light grey") +
  #create chloropleth layer for countries with data
  geom_polygon(data = world4, aes(x = long, y = lat, group = group, fill = interest),
               col = "white") +
  #add map theme from ggthemes
  theme_map() +
  #Set the zoom
  coord_fixed(xlim = c(-130, 160),
              ylim = c(-50, 75), ratio = 1.4) +
  #Add city layer - include col in aes() to get city as a separate legend item
  geom_point(data = city, aes(x= long, y = lat, col = interest),
             shape = 21, inherit.aes = F, size = 3, fill = "yellow") +
  #set fill for countries by interest (include city (special) to have the correct number of aesthetics)
  scale_fill_manual(name = NULL,
                    breaks = c("interest", "past", "current", "special"),
                    values = c(interest = "#a7ef88", past = "#3a7f1d", current = "#1b5104", special = "yellow"), 
                    labels = c("interest", "past", "current", "city")) +
  #set color for cities and labels for cities legend
  scale_color_manual(name = NULL, 
                     breaks = c("special"),
                     values = c(special = "black"),
                     labels = c("cities")) +
  #set order of legend items (fill first)
  guides(fill = guide_legend(order = 1),  color = guide_legend(order = 2)) +
  #set legend position and vertical arrangement
  theme(legend.text = element_text(size = 9), legend.position = "bottom", legend.box = "vertical")

Gives the following:

enter image description here

MorrisseyJ
  • 1,191
  • 12
  • 19