2017-03-10 16 views
3

ggplot2の議席に議席の大きさを表示するグラフを作成したいと思います。私の主な問題は、本質的に、ドーナツチャートを半分のドーナツチャートにする方法です。ハーフドーナツ(議会議席)を作成する図表

例として上に画像を使用して

Parliament chart

、私はここから行くかわからないん

df <- data.frame(Party = c("GUE/NGL", "S&D", "Greens/EFA", "ALDE", "EPP", "ECR", "EFD", "NA"), 
          Number = c(35, 184, 55, 84, 265, 54, 32, 27)) 
df$Party <- factor(df$Party) 
df$Share <- df$Number/sum(df$Number) 
df$ymax <- cumsum(df$Share) 
df$ymin <- c(0, head(df$ymax, n= -1)) 

ggplot(df, aes(fill = Party, ymax = ymax, ymin = ymin, xmax = 2, xmin = 1)) + geom_rect() + 
coord_polar(theta = "y") + xlim(c(0, 2)) 

enter image description here

+0

私は 'ハック方法この種の(HTTP以外のggplot'にはわからない://あなたは '循環 'パッケージ(http://www.w3.org/questions/22398350/how-to-show-only-part-of-the-plot-area-of-polar-ggplot-with-facet)をチェックアウトすることができます。 /stackoverflow.com/questions/33168771/creating-half-a-polar-plot-rose-diagram-with- circular-package) – Lucy

+1

mebbe https://github.com/leeper/ggparliament? – hrbrmstr

答えて

5

この仕事はあなたのためでしょうか?

ggplot(df, aes(fill = Party, ymax = ymax, ymin = ymin, xmax = 2, xmin = 1)) + geom_rect() + 
    coord_polar(theta = "y",start=-pi/2) + xlim(c(0, 2)) + ylim(c(0,2)) 

基本的にはちょうどそれが唯一の半分にそれをプロットして、あなたの最大2倍されるylimを設定します。この場合、yの制限を0から2に設定します。次に、coord_polar(start=)の開始位置をオフセットして、適切な場所に配置します。

enter image description here

6

FWIW、1も素敵ggforceパッケージチェックアウトするかもしれません:あなたは単位円のプロパティを使用することができるなどのラベルを取得するには

library(tidyverse) 
library(ggforce) 
library(scales) 
df %>% 
    mutate_at(vars(starts_with("y")), rescale, to=pi*c(-.5,.5), from=0:1) %>% 
    ggplot + 
    geom_arc_bar(aes(x0 = 0, y0 = 0, r0 = .5, r = 1, start = ymin, end = ymax, fill=Party)) + 
    coord_fixed() 

enter image description here

+0

'geom_text()'(例えば、座席数)のラベルを、それぞれ対応するスライスの中央に配置する方法を教えてください。 – Phil

3

を!私は、あなたの質問にプロットのスタイルを再作成しようとしている小さな関数を書いた:)

library(ggforce) 

parlDiag <- function(Parties, shares, cols = NULL, repr=c("absolute", "proportion")) { 
    repr = match.arg(repr) 
    stopifnot(length(Parties) == length(shares)) 
    if (repr == "proportion") { 
    stopifnot(sum(shares) == 1) 
    } 
    if (!is.null(cols)) { 
    names(cols) <- Parties 
    } 

    # arc start/end in rads, last one reset bc rounding errors 
    cc <- cumsum(c(-pi/2, switch(repr, "absolute" = (shares/sum(shares)) * pi, "proportion" = shares * pi))) 
    cc[length(cc)] <- pi/2 

    # get angle of arc midpoints 
    meanAngles <- colMeans(rbind(cc[2:length(cc)], cc[1:length(cc)-1])) 

    # unit circle 
    labelX <- sin(meanAngles) 
    labelY <- cos(meanAngles) 

    # prevent bounding box < y=0 
    labelY <- ifelse(labelY < 0.015, 0.015, labelY) 

    p <- ggplot() + theme_no_axes() + coord_fixed() + 
    expand_limits(x = c(-1.3, 1.3), y = c(0, 1.3)) + 
    theme(panel.border = element_blank()) + 
    theme(legend.position = "none") + 

    geom_arc_bar(aes(x0 = 0, y0 = 0, r0 = 0.5, r = 1, 
        start = cc[1:length(shares)], 
        end = c(cc[2:length(shares)], pi/2), fill = Parties)) + 

    switch(is.null(cols)+1, scale_fill_manual(values = cols), NULL) + 

    # for label and line positions, just scale sin & cos to get in and out of arc 
    geom_path(aes(x = c(0.9 * labelX, 1.15 * labelX), y = c(0.9 * labelY, 1.15 * labelY), 
        group = rep(1:length(shares), 2)), colour = "white", size = 2) + 
    geom_path(aes(x = c(0.9 * labelX, 1.15 * labelX), y = c(0.9 * labelY, 1.15 * labelY), 
        group = rep(1:length(shares), 2)), size = 1) + 

    geom_label(aes(x = 1.15 * labelX, y = 1.15 * labelY, 
        label = switch(repr, 
            "absolute" = sprintf("%s\n%i", Parties, shares), 
            "proportion" = sprintf("%s\n%i%%", Parties, round(shares*100)))), fontface = "bold", 
       label.padding = unit(1, "points")) + 

    geom_point(aes(x = 0.9 * labelX, y = 0.9 * labelY), colour = "white", size = 2) + 
    geom_point(aes(x = 0.9 * labelX, y = 0.9 * labelY)) + 
    geom_text(aes(x = 0, y = 0, label = switch(repr, 
               "absolute" = (sprintf("Total: %i MPs", sum(shares))), 
               "proportion" = "")), 
       fontface = "bold", size = 7) 

    return(p) 
} 

bt <- data.frame(parties = c("CDU", "CSU", "SPD", "AfD", "FDP", "Linke", "Grüne", "Fraktionslos"), 
       seats = c(200, 46, 153, 92, 80, 69, 67, 2), 
       cols = c("black", "blue", "red", "lightblue", "yellow", "purple", "green", "grey"), 
       stringsAsFactors = FALSE) 

parlDiag(bt$parties, bt$seats, cols = bt$cols) 

enter image description here

+0

これは素晴らしく、これを設定する時間に感謝します。 – Phil

関連する問題