15

Another interesting ggplot2 challenge! I'm trying to create a ggsubplot call that gives pie charts over a world map. The tough thing seems to be that pie charts in ggplot2 are stacked bar charts with polar coordinates, and that addition of coord_polar affects not just the subplot geom but the whole map itself. Does anyone know how to apply a certain coordinate scheme only to only one part of the subplot call? This is what I have so far:

library(ggplot2)
library(maps)
library(mapproj)
#install.packages("devtools")
library(devtools)
# install ggsubplot from github repo, not currently on CRAN
install_github(username="garrettgman", repo="ggsubplot")

world = map_data("world")

loc_pie = structure(list(Region = structure(c(3L, 5L, 7L, 8L, 9L, 10L, 
11L, 12L, 13L, 15L, 16L, 2L, 14L, 2L, 4L, 5L, 6L, 7L, 9L, 10L
), .Label = c("", "ANT/SO", "ARC", "EPR/GAL", "GOM/CAR", "IND", 
"MAR", "MED", "N-ATL", "NE-ATL", "NE-PAC", "NW-ATL", "NW-PAC", 
"SE-ATL", "SE-PAC", "SW-ATL", "SW-PAC"), class = "factor"), Group3 = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L), .Label = c("Annelida", "Choanoflagellata", "Chordata", 
"Cnidaria", "Crustacea", "Echinodermata", "Foraminifera", "Mollusca", 
"Nematoda", "Other", "Platyhelminthes", "Porifera"), class = "factor"), 
ones = c(1, 1, 5, 1, 1, 1, 18, 3, 1, 4, 8, 1, 1, 2, 1, 1, 
6, 1, 2, 5), tot = c(5, 30, 11, 16, 28, 22, 51, 25, 78, 13, 
32, 57, 61, 57, 15, 30, 20, 11, 28, 22), div = c(0.2, 0.0333333333333333, 
0.454545454545455, 0.0625, 0.0357142857142857, 0.0454545454545455, 
0.352941176470588, 0.12, 0.0128205128205128, 0.307692307692308, 
0.25, 0.0175438596491228, 0.0163934426229508, 0.0350877192982456, 
0.0666666666666667, 0.0333333333333333, 0.3, 0.0909090909090909, 
0.0714285714285714, 0.227272727272727), lat = c(71.4493167, 
19.9897167, 23.5874333, 37.6802167, 55.13365, 36.6889333, 
35.9565333, 35.53935, 30.4266, -30.32195, -33.2038, -65.8756333, 
-17.12415, -65.8756333, 0.1135, 19.9897167, -14.5800667, 
23.5874333, 55.13365, 36.6889333), long = c(-1.0550667, -81.3430667, 
-41.2278667, 15.9298833, -30.4984333, -17.4906167, -149.4363333, 
-63.01795, 156.3570833, -110.23255, -31.20155, -25.4557, 
0.0881833, -25.4557, -101.07455, -81.3430667, 77.4312667, 
-41.2278667, -30.4984333, -17.4906167)), .Names = c("Region", 
"Group3", "ones", "tot", "div", "lat", "long"), row.names = c(NA, 
20L), class = "data.frame")

ggplot(data=loc_pie) + geom_polygon(data=world, aes(x=long, y=lat, group =group),colour="grey40", fill="grey40") + geom_subplot(height=12, aes(long, lat, group=Region, subplot = (geom_bar(aes(x = factor(1),   y=div, fill=factor(Group3)), width =1, height = 2,stat="identity"))))

Doesn't look like I can post images because I'm a new user.

![world map with stacked bar chart subplots][1]

Any ideas on how to incorporate the polar coordinates for only the subplot? Thanks so much.

alj0217
  • 151
  • 4
  • 2
    Hi! It would be very helpful to have a [minimal reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) so we can reproduce the problem ourselves. – colcarroll Nov 18 '13 at 17:08
  • Yes, thanks for the suggestion. Made edits that should allow a more basic reproduction. – alj0217 Nov 18 '13 at 19:01
  • 1
    `ggsubplot` is not on CRAN. Please help people to help you by making your code reproducible, i.e. add code that runs smoothly, including code for installing necessary packages. Thanks. – Henrik Nov 18 '13 at 20:20
  • Right, sorry. It seems like it's been on and off CRAN, and may go back up soon. For now, looks like you can get previous versions from cran or install it through github with the code I've added above. Thanks! – alj0217 Nov 18 '13 at 21:19
  • that does explain how to do this in the base graphics package, but presumably it is now possible in ggplot2 with the addition of ggsubplot. thanks for the link! – alj0217 Nov 18 '13 at 23:27
  • @alj0217. I also want to make pie chart over a world map. So far I managed to plot histogram on the top of the map but not the pie charts yet. Did find a way to do it at the end? Thanks – Simon Besnard Jan 25 '15 at 19:32
  • @SimonBesnard no, unfortunately not. plotted them separately and then used an image editor. – alj0217 Jul 23 '15 at 22:36

3 Answers3

1

Here is a solution with the latest version of ggplot2 and ggtree:

library(maps)
library(mapproj)
library(ggplot2)
library(ggtree)
library(dplyr)
library(magrittr)

world = map_data("world")

p <- ggplot(data=world, aes(x=long, y=lat, group =group)) + geom_polygon(colour="grey40", fill="grey40")

for (name in unique(loc_pie[['Region']])) {
  loc_region <- filter(loc_pie, Region %in% name)
  pie_tmp <- ggplot(data = loc_region, aes(x = factor(1), y = div, fill = Group3)) +
    geom_bar(width = 1, stat = "identity") + coord_polar(theta = "y") +
    scale_fill_discrete(drop = FALSE) +
    xlab(NULL) + ylab(NULL) + theme_tree() +
    theme_transparent()
  lat_region <- loc_region[[1,'lat']]
  long_region <- loc_region[[1,'long']]
  p %<>% subview(pie_tmp, long_region, lat_region, width = .07, height = .07)
}

p

The width ang height have been picked manually, they correspond to the proportion of the subview with respect to the full one.

For sake of completness, loc_pie can be obtained by:

loc_pie = structure(
  list(
    Region = structure(
      c(
        3L,
        5L,
        7L,
        8L,
        9L,
        10L,
        11L,
        12L,
        13L,
        15L,
        16L,
        2L,
        14L,
        2L,
        4L,
        5L,
        6L,
        7L,
        9L,
        10L
      ),
      .Label = c(
        "",
        "ANT/SO",
        "ARC",
        "EPR/GAL",
        "GOM/CAR",
        "IND",
        "MAR",
        "MED",
        "N-ATL",
        "NE-ATL",
        "NE-PAC",
        "NW-ATL",
        "NW-PAC",
        "SE-ATL",
        "SE-PAC",
        "SW-ATL",
        "SW-PAC"
      ),
      class = "factor"
    ),
    Group3 = structure(
      c(
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        1L,
        2L,
        2L,
        3L,
        3L,
        3L,
        3L,
        3L,
        3L,
        3L
      ),
      .Label = c(
        "Annelida",
        "Choanoflagellata",
        "Chordata",
        "Cnidaria",
        "Crustacea",
        "Echinodermata",
        "Foraminifera",
        "Mollusca",
        "Nematoda",
        "Other",
        "Platyhelminthes",
        "Porifera"
      ),
      class = "factor"
    ),
    ones = c(1, 1, 5, 1, 1, 1, 18, 3, 1, 4, 8, 1, 1, 2, 1, 1,
             6, 1, 2, 5),
    tot = c(5, 30, 11, 16, 28, 22, 51, 25, 78, 13,
            32, 57, 61, 57, 15, 30, 20, 11, 28, 22),
    div = c(
      0.2,
      0.0333333333333333,
      0.454545454545455,
      0.0625,
      0.0357142857142857,
      0.0454545454545455,
      0.352941176470588,
      0.12,
      0.0128205128205128,
      0.307692307692308,
      0.25,
      0.0175438596491228,
      0.0163934426229508,
      0.0350877192982456,
      0.0666666666666667,
      0.0333333333333333,
      0.3,
      0.0909090909090909,
      0.0714285714285714,
      0.227272727272727
    ),
    lat = c(
      71.4493167,
      19.9897167,
      23.5874333,
      37.6802167,
      55.13365,
      36.6889333,
      35.9565333,
      35.53935,
      30.4266,
      -30.32195,
      -33.2038,
      -65.8756333,-17.12415,
      -65.8756333,
      0.1135,
      19.9897167,
      -14.5800667,
      23.5874333,
      55.13365,
      36.6889333
    ),
    long = c(
      -1.0550667,
      -81.3430667,-41.2278667,
      15.9298833,
      -30.4984333,
      -17.4906167,
      -149.4363333,-63.01795,
      156.3570833,
      -110.23255,
      -31.20155,
      -25.4557,
      0.0881833,
      -25.4557,
      -101.07455,
      -81.3430667,
      77.4312667,-41.2278667,
      -30.4984333,
      -17.4906167
    )
  ),
  .Names = c("Region",
             "Group3", "ones", "tot", "div", "lat", "long"),
  row.names = c(NA,
                20L),
  class = "data.frame"
)
Erwan LE PENNEC
  • 516
  • 3
  • 10
0

The following sort of works, but doesn't use ggsubplot.

library(sp)
library(plotGoogleMaps)

loc_pie$divc = 1-loc_pie$div
coordinates(loc_pie) <- ~long+lat
proj4string(loc_pie) <- CRS("+proj=longlat")
m <- segmentGoogleMaps(loc_pie,zcol=c('div','divc'), 
                       scalelist=FALSE,
                       max.radius=1000000,
                       mapTypeId = "ROADMAP",
                       legend = FALSE, control = FALSE)

I haven't been able to figure out how to get that function to make all the bubbles the same size. It seems to be ignoring some of the arguments like scalelist and bounds. Plotly also kind of works, as long as you're willing to have the single value of div encoded as color or size:

library(plotly)
loc_pie$hover <- paste(loc_pie$div*100,"%")
g <- list(
  scope = 'world',
  projection = list(type = "mercator"),
  showland = TRUE,
  landcolor = toRGB("gray85"),
  subunitwidth = 1,
  countrywidth = 1,
  subunitcolor = toRGB("white"),
  countrycolor = toRGB("white")
)
plot_ly(loc_pie, lon = long, lat = lat, text = hover,
        marker = list(size = 100),
        type = 'scattergeo', color=div,
        locationmode = 'country names',geo=g)
atiretoo
  • 1,812
  • 19
  • 33
0

try multiplot function http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2)/ i allows you to plot multiple plots on one window

OR

ggplot, facet, piechart: placing text in the middle of pie chart slices

this is what you are searching

Community
  • 1
  • 1
R Vij
  • 80
  • 1
  • 11