Pertanyaan memplot grafik pie pada peta di ggplot


Ini mungkin merupakan hal daftar keinginan, tidak yakin (yaitu mungkin perlu dibuatnya geom_pie agar ini terjadi). Saya melihat peta hari ini (LINK) dengan grafik pai di atasnya seperti yang terlihat di sini. enter image description here

Saya tidak ingin memperdebatkan manfaat grafik pai, ini lebih merupakan latihan yang dapat saya lakukan ini di ggplot?

Saya telah menyediakan satu set data di bawah ini (dimuat dari kotak drop saya) yang memiliki data pemetaan untuk membuat peta Negara Bagian New York dan beberapa data yang dibuat murni pada persentase rasial menurut county. Saya telah memberikan rasial ini sebagai gabungan dengan kumpulan data utama dan sebagai kumpulan data terpisah yang disebut kunci. Saya juga berpikir tanggapan Bryan Goodrich kepada saya di posting lain (SINI) pada pemusatan nama daerah akan membantu konsep ini.

Bagaimana kita bisa membuat peta di atas dengan ggplot2?

Kumpulan data dan peta tanpa grafik pai:

load(url("http://dl.dropbox.com/u/61803503/nycounty.RData"))
head(ny); head(key)  #view the data set from my drop box
library(ggplot2)
ggplot(ny, aes(long, lat, group=group)) +  geom_polygon(colour='black', fill=NA)

#  Now how can we plot a pie chart of race on each county 
#  (sizing of the pie would also be controllable via a size 
#  parameter like other `geom_` functions).

Terima kasih sebelumnya atas gagasan Anda.

EDIT: Saya baru saja melihat kasus lain junkcharts yang berteriak untuk jenis kemampuan ini: enter image description here


32
2018-04-28 22:40


asal


Jawaban:


Tiga tahun kemudian ini terpecahkan. Saya telah mengumpulkan sejumlah proses bersama dan terima kasih kepada @Guangchuang Yu yang luar biasa ggtree paket ini bisa dilakukan dengan cukup mudah. Perhatikan bahwa pada (9/3/2015) Anda harus memiliki versi 1.0.18 dari ggtree diinstal tetapi ini akhirnya akan menetes ke masing-masing repositori.

enter image description here

Saya telah menggunakan sumber daya berikut untuk membuat ini (tautan akan memberikan detail lebih besar):

  1. ggtree blog
  2. pindahkan legenda ggplot 
  3. versi ggtree yang benar
  4. memusatkan hal-hal dalam poligon

Begini kodenya:

load(url("http://dl.dropbox.com/u/61803503/nycounty.RData"))
head(ny); head(key)  #view the data set from my drop box

if (!require("pacman")) install.packages("pacman")
p_load(ggplot2, ggtree, dplyr, tidyr, sp, maps, pipeR, grid, XML, gtable)

getLabelPoint <- function(county) {Polygon(county[c('long', 'lat')])@labpt}

df <- map_data('county', 'new york')                 # NY region county data
centroids <- by(df, df$subregion, getLabelPoint)     # Returns list
centroids <- do.call("rbind.data.frame", centroids)  # Convert to Data Frame
names(centroids) <- c('long', 'lat')                 # Appropriate Header

pops <-  "http://data.newsday.com/long-island/data/census/county-population-estimates-2012/" %>%
     readHTMLTable(which=1) %>%
     tbl_df() %>%
     select(1:2) %>%
     setNames(c("region", "population")) %>%
     mutate(
         population = {as.numeric(gsub("\\D", "", population))},
         region = tolower(gsub("\\s+[Cc]ounty|\\.", "", region)),
         #weight = ((1 - (1/(1 + exp(population/sum(population)))))/11) 
         weight = exp(population/sum(population)),
         weight = sqrt(weight/sum(weight))/3
     )


race_data_long <- add_rownames(centroids, "region") %>>%
    left_join({distinct(select(ny, region:other))}) %>>%
    left_join(pops) %>>%
    (~ race_data) %>>%
    gather(race, prop, white:other) %>%
    split(., .$region)

pies <- setNames(lapply(1:length(race_data_long), function(i){
    ggplot(race_data_long[[i]], aes(x=1, prop, fill=race)) +
        geom_bar(stat="identity", width=1) + 
        coord_polar(theta="y") + 
        theme_tree() + 
        xlab(NULL) + 
        ylab(NULL) + 
        theme_transparent() +
        theme(plot.margin=unit(c(0,0,0,0),"mm"))
}), names(race_data_long))


e1 <- ggplot(race_data_long[[1]], aes(x=1, prop, fill=race)) +
        geom_bar(stat="identity", width=1) + 
        coord_polar(theta="y") 

leg1 <- gtable_filter(ggplot_gtable(ggplot_build(e1)), "guide-box") 


p <- ggplot(ny, aes(long, lat, group=group)) +  
    geom_polygon(colour='black', fill=NA) +
    theme_bw() +
    annotation_custom(grob = leg1, xmin = -77.5, xmax = -78.5, ymin = 44, ymax = 45) 



n <- length(pies)

for (i in 1:n) {

    nms <- names(pies)[i]
    dat <- race_data[which(race_data$region == nms)[1], ]
    p <- subview(p, pies[[i]], x=unlist(dat[["long"]])[1], y=unlist(dat[["lat"]])[1], dat[["weight"]], dat[["weight"]])

}

print(p)

24
2017-09-03 15:58



Fungsionalitas ini harus ada di ggplot, saya pikir ini akan segera datang ke ggplot, tetapi saat ini tersedia di petak dasar. Saya pikir saya akan memposting ini hanya demi perbandingan.

load(url("http://dl.dropbox.com/u/61803503/nycounty.RData"))

library(plotrix)
e=10^-5
myglyff=function(gi) {
floating.pie(mean(gi$long),
             mean(gi$lat),
             x=c(gi[1,"white"]+e,
                 gi[1,"black"]+e,
                 gi[1,"hispanic"]+e,
                 gi[1,"asian"]+e,
                 gi[1,"other"]+e),
              radius=.1) #insert size variable here
}

g1=ny[which(ny$group==1),]
plot(g1$long,
     g1$lat,
     type='l',
     xlim=c(-80,-71.5),
     ylim=c(40.5,45.1))

myglyff(g1)

for(i in 2:62)
  {gi=ny[which(ny$group==i),]
    lines(gi$long,gi$lat)
    myglyff(gi)
  }

Juga, mungkin ada (mungkin) cara-cara yang lebih elegan untuk melakukan hal ini dalam grafik dasar.

It's a New York Pie!!

Seperti yang Anda lihat, ada beberapa masalah dengan hal ini yang perlu dipecahkan. Warna isian untuk kabupaten. Pie chart cenderung terlalu kecil atau tumpang tindih. Bagian lat dan long tidak mengambil proyeksi sehingga ukuran wilayah terdistorsi.

Dalam hal apa pun, saya tertarik dengan apa yang dapat dihasilkan oleh orang lain.


14
2017-07-31 20:37



Saya telah menulis beberapa kode untuk melakukan ini menggunakan grafik grid. Ada sebuah contoh di sini: https://qdrsite.wordpress.com/2016/06/26/pies-on-a-map/

Tujuannya di sini adalah mengaitkan diagram lingkaran dengan titik-titik tertentu di peta, dan belum tentu wilayah. Untuk solusi khusus ini, perlu mengonversi koordinat peta (garis lintang dan garis bujur) menjadi skala (0,1) sehingga dapat diplot di lokasi yang tepat di peta. Paket grid digunakan untuk mencetak ke viewport yang berisi panel plot.

Kode:

# Pies On A Map
# Demonstration script
# By QDR

# Uses NLCD land cover data for different sites in the National Ecological Observatory Network.
# Each site consists of a number of different plots, and each plot has its own land cover classification.
# On a US map, plot a pie chart at the location of each site with the proportion of plots at that site within each land cover class.

# For this demo script, I've hard coded in the color scale, and included the data as a CSV linked from dropbox.

# Custom color scale (taken from the official NLCD legend)
nlcdcolors <- structure(c("#7F7F7F", "#FFB3CC", "#00B200", "#00FFFF", "#006600", "#E5CC99", "#00B2B2", "#FFFF00", "#B2B200", "#80FFCC"), .Names = c("unknown", "cultivatedCrops", "deciduousForest", "emergentHerbaceousWetlands", "evergreenForest", "grasslandHerbaceous", "mixedForest", "pastureHay", "shrubScrub", "woodyWetlands"))

# NLCD data for the NEON plots
nlcdtable_long <- read.csv(file='https://www.dropbox.com/s/x95p4dvoegfspax/demo_nlcdneon.csv?raw=1', row.names=NULL, stringsAsFactors=FALSE)

library(ggplot2)
library(plyr)
library(grid)

# Create a blank state map. The geom_tile() is included because it allows a legend for all the pie charts to be printed, although it does not
statemap <- ggplot(nlcdtable_long, aes(decimalLongitude,decimalLatitude,fill=nlcdClass)) +
geom_tile() +
borders('state', fill='beige') + coord_map() +
scale_x_continuous(limits=c(-125,-65), expand=c(0,0), name = 'Longitude') +
scale_y_continuous(limits=c(25, 50), expand=c(0,0), name = 'Latitude') +
scale_fill_manual(values = nlcdcolors, name = 'NLCD Classification')

# Create a list of ggplot objects. Each one is the pie chart for each site with all labels removed.
pies <- dlply(nlcdtable_long, .(siteID), function(z)
ggplot(z, aes(x=factor(1), y=prop_plots, fill=nlcdClass)) +
geom_bar(stat='identity', width=1) +
coord_polar(theta='y') +
scale_fill_manual(values = nlcdcolors) +
theme(axis.line=element_blank(),
axis.text.x=element_blank(),
axis.text.y=element_blank(),
axis.ticks=element_blank(),
axis.title.x=element_blank(),
axis.title.y=element_blank(),
legend.position="none",
panel.background=element_blank(),
panel.border=element_blank(),
panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),
plot.background=element_blank()))

# Use the latitude and longitude maxima and minima from the map to calculate the coordinates of each site location on a scale of 0 to 1, within the map panel.
piecoords <- ddply(nlcdtable_long, .(siteID), function(x) with(x, data.frame(
siteID = siteID[1],
x = (decimalLongitude[1]+125)/60,
y = (decimalLatitude[1]-25)/25
)))

# Print the state map.
statemap

# Use a function from the grid package to move into the viewport that contains the plot panel, so that we can plot the individual pies in their correct locations on the map.
downViewport('panel.3-4-3-4')

# Here is the fun part: loop through the pies list. At each iteration, print the ggplot object at the correct location on the viewport. The y coordinate is shifted by half the height of the pie (set at 10% of the height of the map) so that the pie will be centered at the correct coordinate.
for (i in 1:length(pies)) 
  print(pies[[i]], vp=dataViewport(xData=c(-125,-65), yData=c(25,50), clip='off',xscale = c(-125,-65), yscale=c(25,50), x=piecoords$x[i], y=piecoords$y[i]-.06, height=.12, width=.12))

Hasilnya terlihat seperti ini:

map with pies


5
2018-06-26 21:46



Saya menemukan apa yang tampak seperti fungsi untuk melakukan ini: "add.pie" di paket "mapplots".

Contoh dari paket di bawah.

plot(NA,NA, xlim=c(-1,1), ylim=c(-1,1) )
add.pie(z=rpois(6,10), x=-0.5, y=0.5, radius=0.5)
add.pie(z=rpois(4,10), x=0.5, y=-0.5, radius=0.3)

1
2017-07-11 06:09



Sedikit variasi pada persyaratan asli OP, tapi ini sepertinya jawaban / pembaruan yang tepat.

Jika Anda ingin Google Map interaktif, pada googleway v2.6.0 Anda dapat menambahkan bagan di dalamnya info_windows lapisan peta.

Lihat ?googleway::google_charts untuk dokumentasi dan contoh

library(googleway)

set_key("GOOGLE_MAP_KEY")

## create some dummy chart data
markerCharts <- data.frame(stop_id = rep(tram_stops$stop_id, each = 3))
markerCharts$variable <- c("yes", "no", "maybe")
markerCharts$value <- sample(1:10, size = nrow(markerCharts), replace = T)

chartList <- list(
  data = markerCharts
  , type = 'pie'
  , options = list(
    title = "my pie"
    , is3D = TRUE
    , height = 240
    , width = 240
    , colors = c('#440154', '#21908C', '#FDE725')
    )
  )

google_map() %>%
  add_markers(
    data = tram_stops
    , id = "stop_id"
    , info_window = chartList
  )

enter image description here


0
2018-06-18 10:18