【问题标题】:Putting two Pie Charts in one将两个饼图合二为一
【发布时间】:2014-06-01 20:13:29
【问题描述】:

我正在尝试使用 R 中的以下数据创建饼图:

    2009    2010
US  10  12
UK  13  14
Germany 18  11
China   9   8
Malaysia    7   15
Others  13  15

我使用的命令是:

slices<-c(10,13,18,9,7,13,12,14,11,8,15,15)
 lbls <- c("US","UK","Germany","China", "Malaysia", "Others","US","UK","Germany","China", "Malaysia", "Others") 
 pct <- round(slices/sum(slices)*100)
 lbls <- paste(lbls,"%",sep="")
 lbls <- paste(lbls, pct)
 pie(slices,labels = lbls, col=rainbow(length(lbls)),  main="Pie Chart of Countries")

我得到的图

现在如何配置图表以使国家/地区具有相同的配色方案?他们按照相同的顺序分成两半,比如首先应该是美国和英国等等。

两个简化问题我想在一个饼图中制作两个饼图,其中饼图的一半代表2009年,另一半代表2010年。

请帮忙。

谢谢

【问题讨论】:

    标签: r plot pie-chart


    【解决方案1】:
     lbls0 <- c("US","UK","Germany","China", "Malaysia", "Others","US","UK","Germany","China", "Malaysia", "Others") 
     pct <- round(slices/sum(slices)*100)
     lbls <- paste(lbls,"%",sep="")
     lbls <- paste(lbls, pct)
     pie(slices,labels = lbls, col=rainbow(length(lbls)),
          main="Pie Chart of Countries")
    
    
     nlbl <- length(lbls)
     yrs <- rep(2009:2010,each=nlbl/2)
     xlbls <- sprintf("%s (%d) %d%%",lbls0,yrs,pct)
     pie(slices,labels = xlbls, col=rep(rainbow(nlbl/2),2),
          main="Pie Chart of Countries")
    

    您是否愿意考虑一种更容易进行定量比较的可视化形式?

     library(ggplot2); theme_set(theme_bw())
     dd <- data.frame(lbls0,yrs,slices,pct)
     dd$lbls0 <- reorder(dd$lbls0,-dd$slices)
     ggplot(dd,aes(x=lbls0,y=slices,fill=lbls0))+
        geom_bar(aes(alpha=factor(yrs)),
                        stat="identity",position=position_dodge(width=1))+
        scale_alpha_discrete(range=c(0.7,1.0))+
        geom_text(aes(label=paste0(pct,"%"),
                  group=interaction(lbls0,yrs)),hjust=-0.2,
                  position=position_dodge(width=1))+
                      coord_flip()+
        expand_limits(y=20)+labs(x="",y="total")
    

    如果您更感兴趣的是年份内国家之间的比较,而不是国家内年份之间的比较,您可以跳过 scale_alpha 的内容并使用 facet_wrap(~yrs) ...

    【讨论】:

    • 嗨,Ben,感谢您的回答,因为我正在寻找饼状图中的东西,所以我不会使用条形图。但是您的饼图也很棒(+1)。谢谢你:)
    • 我鼓励你阅读great pie chart debate 并形成你自己的结论......
    • +1 用于回答 OP 的问题; +很棒的带领他们做出更好的选择。
    • @BenBolker 关于饼图的用处:这在 R 的帮助页面中也得到了认可(请参阅我对引用的回答)。
    • 是的,但是在两个方向上都有争论——克利夫兰 1985 年的论文远不是关于这个主题的最后一句话......
    【解决方案2】:

    您可以在 reshape2 包的帮助下解决这个问题:

    # reading the data
    df <- read.table(header=TRUE, text="Country   2009    2010
    US  10  12
    UK  13  14
    Germany 18  11
    China   9   8
    Malaysia    7   15
    Others  13  15")
    
    # setting the column names correct
    colnames(df) <- c("Country","2009","2010")
    
    # reshaping the dataframe
    require(reshape2)
    df2 <- melt(df, id="Country")
    
    # creating the plot
    pie(df2$value, labels=paste0(df2$Country," (",df2$variable,") ",df2$value,"%"),
        col=rainbow(length(levels(df2$Country))), main="Pie Chart of Countries")
    

    给出:


    对于年份标签的变体,您还可以使用:

    pie(df2$value, labels=paste0(df2$Country," ",df2$value,"%"),
        col=rainbow(length(levels(df2$Country))), main="Pie Chart of Countries")
    mtext("2009",side=3)
    mtext("2010",side=1)
    

    给出:


    正如@BenBolker 所说,饼图不是呈现数据的好方法。值得引用帮助页面 ?pie 如果这也被识别:

    饼图是一种非常糟糕的信息显示方式。眼睛擅长判断线性度量,不擅长判断相对区域。条形图或点状图是显示此类数据的首选方式。

    Cleveland (1985),第 264 页:“可以通过饼图显示的数据始终可以通过点图显示。这意味着可以沿着一个共同的尺度来判断位置,而不是不太准确的角度判断。”该声明基于对克利夫兰和麦吉尔的实证调查以及感性心理学家的调查。

    【讨论】:

      【解决方案3】:

      这可能有效。至少两半具有相同的配色方案。我不确定你所说的相同顺序是什么意思。

      slices<-c(10,13,18,9,7,13,12,14,11,8,15,15)
      pct   <- round(slices/sum(slices)*100)
      
      lbls <- c("US","UK","Germany","China", "Malaysia", "Others","US","UK","Germany","China", "Malaysia", "Others") 
      lbls <- paste(lbls,"%",sep="")
      lbls <- paste(lbls, pct)
      
      col  <- c("yellow", "orange", "red", "purple", "blue", "green", "yellow", "orange", "red", "purple", "blue", "green")
      
      pie(slices,labels = lbls,  main="Pie Chart of Countries", col = col)
      

      您可以使用

      缩短 col 代码
      col  <- rep(c("yellow", "orange", "red", "purple", "blue", "green"),2)
      

      我不确定你想要什么两半。如果您想将每一半的百分比标准化为 50%,这可能会起作用:

      a <- c(7, 9, 12, 6, 5, 9)
      a2 <- (a/sum(a)) * 50
      a2
      # [1]  7.291667  9.375000 12.500000  6.250000  5.208333  9.375000
      
      b <- c(8, 10, 8, 6, 10, 10)
      b2 <- (b/sum(b)) * 50
      b2
      # [1] 7.692308 9.615385 7.692308 5.769231 9.615385 9.615385
      
      pct <- round(c(a2,b2),2)
      pct
      

      【讨论】:

      • 嗨,是的,它确实解决了配色方案的问题。但是,如何将区域平均分成两个半圆(或半饼),其中一半代表 2009 年的数据,另一半代表 2010 年的数据。
      • 感谢您的复选标记,但也可以考虑使用@BenBolker 的答案。
      • @MarkMiller 看到我的答案了吗?我很好奇如何看待这种方法
      • @Jaap 我喜欢。看起来很好。我真的很喜欢这些标签,而且你的颜色分配声明聪明而简洁。我复制了您和 Ben 的代码,并将其放入我的代码库中以供将来参考。
      • @MarkMiller 最后一个如何制作标签图例而不是在图形本身中标记它们
      【解决方案4】:

      这是另一个类似于我的答案here的解决方案

      slices <- c(10,13,18,9,7,13,12,14,11,8,15,15)
      lbls <- c("US","UK","Germany","China", "Malaysia", "Others","US","UK","Germany","China", "Malaysia", "Others") 
      pct  <- round(slices/sum(slices)*100)
      lbls <- paste(lbls,"%",sep="")
      lbls <- paste(lbls, pct)
      
      
      dat <- data.frame(year = rep(c(2009, 2010), each = 6), lbls, slices)
      dat$total <- with(dat, ave(slices, year, FUN = sum))
      
      
      plot.new()
      
      par(new = TRUE)
      pie(dat$slices, border = NA, radius = 1,
          col = rainbow(length(lbls) / 2), labels = lbls,
          main = 'Pie Chart of Countries')
      
      par(new = TRUE)
      c2 <- c('grey50', 'grey75')[factor(dat$year)]
      pie(dat$slices, border = c2, radius = .7, col = c2, labels = NA)
      
      text(0, c(.3, -.3), 2009:2010)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-03-25
        • 1970-01-01
        • 2021-12-03
        • 2015-12-30
        • 2019-05-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多