ggplot2 饼图和圆环图在同一图上

2023-12-12

I am trying to replicate this enter image description here with R ggplot. I have exactly the same data:

browsers<-structure(list(browser = structure(c(3L, 3L, 3L, 3L, 2L, 2L, 
2L, 1L, 5L, 5L, 4L), .Label = c("Chrome", "Firefox", "MSIE", 
"Opera", "Safari"), class = "factor"), version = structure(c(5L, 
6L, 7L, 8L, 2L, 3L, 4L, 1L, 10L, 11L, 9L), .Label = c("Chrome 10.0", 
"Firefox 3.5", "Firefox 3.6", "Firefox 4.0", "MSIE 6.0", "MSIE 7.0", 
"MSIE 8.0", "MSIE 9.0", "Opera 11.x", "Safari 4.0", "Safari 5.0"
), class = "factor"), share = c(10.85, 7.35, 33.06, 2.81, 1.58, 
13.12, 5.43, 9.91, 1.42, 4.55, 1.65), ymax = c(10.85, 18.2, 51.26, 
54.07, 55.65, 68.77, 74.2, 84.11, 85.53, 90.08, 91.73), ymin = c(0, 
10.85, 18.2, 51.26, 54.07, 55.65, 68.77, 74.2, 84.11, 85.53, 
90.08)), .Names = c("browser", "version", "share", "ymax", "ymin"
), row.names = c(NA, -11L), class = "data.frame")

它看起来像这样:

> browsers
   browser      version  share   ymax   ymin
1     MSIE     MSIE 6.0  10.85  10.85   0.00
2     MSIE     MSIE 7.0   7.35  18.20  10.85
3     MSIE     MSIE 8.0  33.06  51.26  18.20
4     MSIE     MSIE 9.0   2.81  54.07  51.26
5  Firefox  Firefox 3.5   1.58  55.65  54.07
6  Firefox  Firefox 3.6  13.12  68.77  55.65
7  Firefox  Firefox 4.0   5.43  74.20  68.77
8   Chrome  Chrome 10.0   9.91  84.11  74.20
9   Safari   Safari 4.0   1.42  85.53  84.11
10  Safari   Safari 5.0   4.55  90.08  85.53
11   Opera   Opera 11.x   1.65  91.73  90.08

到目前为止,我已经绘制了各个组件(即版本的圆环图和浏览器的饼图),如下所示:

ggplot(browsers) + geom_rect(aes(fill=version, ymax=ymax, ymin=ymin, xmax=4, xmin=3)) +
coord_polar(theta="y") + xlim(c(0, 4))

enter image description here

ggplot(browsers) + geom_bar(aes(x = factor(1), fill = browser),width = 1) +
coord_polar(theta="y")

enter image description here

问题是,如何将两者结合起来看起来像最上面的图像?我尝试了很多方法,例如:

ggplot(browsers) + geom_rect(aes(fill=version, ymax=ymax, ymin=ymin, xmax=4, xmin=3)) +         geom_bar(aes(x = factor(1), fill = browser),width = 1) + coord_polar(theta="y") + xlim(c(0, 4)) 

但我所有的结果要么扭曲,要么以错误消息结束。


Edit 2

我原来的答案真的很愚蠢。这是一个更短的版本,它通过更简单的界面完成了大部分工作。

#' x      numeric vector for each slice
#' group  vector identifying the group for each slice
#' labels vector of labels for individual slices
#' col    colors for each group
#' radius radius for inner and outer pie (usually in [0,1])

donuts <- function(x, group = 1, labels = NA, col = NULL, radius = c(.7, 1)) {
  group <- rep_len(group, length(x))
  ug  <- unique(group)
  tbl <- table(group)[order(ug)]

  col <- if (is.null(col))
    seq_along(ug) else rep_len(col, length(ug))
  col.main <- Map(rep, col[seq_along(tbl)], tbl)
  col.sub  <- lapply(col.main, function(x) {
    al <- head(seq(0, 1, length.out = length(x) + 2L)[-1L], -1L)
    Vectorize(adjustcolor)(x, alpha.f = al)
  })

  plot.new()

  par(new = TRUE)
  pie(x, border = NA, radius = radius[2L],
      col = unlist(col.sub), labels = labels)

  par(new = TRUE)
  pie(x, border = NA, radius = radius[1L],
      col = unlist(col.main), labels = NA)
}

par(mfrow = c(1,2), mar = c(0,4,0,4))
with(browsers,
     donuts(share, browser, sprintf('%s: %s%%', version, share),
            col = c('cyan2','red','orange','green','dodgerblue2'))
)

with(mtcars,
     donuts(mpg, interaction(gear, cyl), rownames(mtcars))
)

enter image description here


原帖

你们没有givemedonutsorgivemedeath功能?基础图形始终是处理此类非常详细的事情的方法。但无法想出一种优雅的方式来绘制中心饼图标签。

givemedonutsorgivemedeath('~/desktop/donuts.pdf') 

Gives me

enter image description here

请注意,在?pie you see

Pie charts are a very bad way of displaying information.

code:

browsers <- structure(list(browser = structure(c(3L, 3L, 3L, 3L, 2L, 2L, 
  2L, 1L, 5L, 5L, 4L), .Label = c("Chrome", "Firefox", "MSIE", 
  "Opera", "Safari"), class = "factor"), version = structure(c(5L, 
  6L, 7L, 8L, 2L, 3L, 4L, 1L, 10L, 11L, 9L), .Label = c("Chrome 10.0", 
  "Firefox 3.5", "Firefox 3.6", "Firefox 4.0", "MSIE 6.0", "MSIE 7.0", 
  "MSIE 8.0", "MSIE 9.0", "Opera 11.x", "Safari 4.0", "Safari 5.0"), 
  class = "factor"), share = c(10.85, 7.35, 33.06, 2.81, 1.58, 
  13.12, 5.43, 9.91, 1.42, 4.55, 1.65), ymax = c(10.85, 18.2, 51.26, 
  54.07, 55.65, 68.77, 74.2, 84.11, 85.53, 90.08, 91.73), ymin = c(0, 
  10.85, 18.2, 51.26, 54.07, 55.65, 68.77, 74.2, 84.11, 85.53, 
  90.08)), .Names = c("browser", "version", "share", "ymax", "ymin"),
  row.names = c(NA, -11L), class = "data.frame")

browsers$total <- with(browsers, ave(share, browser, FUN = sum))

givemedonutsorgivemedeath <- function(file, width = 15, height = 11) {
  ## house keeping 
  if (missing(file)) file <- getwd()
  plot.new(); op <- par(no.readonly = TRUE); on.exit(par(op))

  pdf(file, width = width, height = height, bg = 'snow')

  ## useful values and colors to work with
  ## each group will have a specific color
  ## each subgroup will have a specific shade of that color
  nr <- nrow(browsers)
  width <- max(sqrt(browsers$share)) / 0.8

  tbl <- with(browsers, table(browser)[order(unique(browser))])
  cols <- c('cyan2','red','orange','green','dodgerblue2')
  cols <- unlist(Map(rep, cols, tbl))

  ## loop creates pie slices
  plot.new()
  par(omi = c(0.5,0.5,0.75,0.5), mai = c(0.1,0.1,0.1,0.1), las = 1)
  for (i in 1:nr) {
    par(new = TRUE)

    ## create color/shades
    rgb <- col2rgb(cols[i])
    f0 <- rep(NA, nr)
    f0[i] <- rgb(rgb[1], rgb[2], rgb[3], 190 / sequence(tbl)[i], maxColorValue = 255)

    ## stick labels on the outermost section
    lab <- with(browsers, sprintf('%s: %s', version, share))
    if (with(browsers, share[i] == max(share))) {
      lab0 <- lab
    } else lab0 <- NA

    ## plot the outside pie and shades of subgroups
    pie(browsers$share, border = NA, radius = 5 / width, col = f0, 
        labels = lab0, cex = 1.8)

    ## repeat above for the main groups
    par(new = TRUE)
    rgb <- col2rgb(cols[i])
    f0[i] <- rgb(rgb[1], rgb[2], rgb[3], maxColorValue = 255)

    pie(browsers$share, border = NA, radius = 4 / width, col = f0, labels = NA)
  }

  ## extra labels on graph

  ## center labels, guess and check?
  text(x = c(-.05, -.05, 0.15, .25, .3), y = c(.08, -.12, -.15, -.08, -.02), 
       labels = unique(browsers$browser), col = 'white', cex = 1.2)

  mtext('Browser market share, April 2011', side = 3, line = -1, adj = 0, 
        cex = 3.5, outer = TRUE)
  mtext('stackoverflow.com:::maryam', side = 3, line = -3.6, adj = 0,
        cex = 1.75, outer = TRUE, font = 3)
  mtext('/questions/26748069/ggplot2-pie-and-donut-chart-on-same-plot',
        side = 1, line = 0, adj = 1.0, cex = 1.2, outer = TRUE, font = 3)
  dev.off()
}

givemedonutsorgivemedeath('~/desktop/donuts.pdf')

Edit 1

width <- 5

tbl <- table(browsers$browser)[order(unique(browsers$browser))]
col.main <- Map(rep, seq_along(tbl), tbl)
col.sub  <- lapply(col.main, function(x)
  Vectorize(adjustcolor)(x, alpha.f = seq_along(x) / length(x)))

plot.new()

par(new = TRUE)
pie(browsers$share, border = NA, radius = 5 / width,
    col = unlist(col.sub), labels = browsers$version)

par(new = TRUE)
pie(browsers$share, border = NA, radius = 4 / width,
    col = unlist(col.main), labels = NA)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ggplot2 饼图和圆环图在同一图上 的相关文章

  • R:使用带有 .Call 和 C/C++ 包装器的 Fortran 子例程而不是 .Fortran 的优点?

    我有一个 R 包 它使用大量 Fortran 子例程来进行递归线性代数计算的嵌套循环 很大程度上依赖于 BLAS 和 LAPACK 例程 作为 Fortran 的接口 我使用 Fortran功能 我刚刚读过乔纳森卡拉汉的博客文章 http
  • 在单个显示器中绘制多个 jpeg 图像

    我需要在单个组合显示器 或画布 中绘制和显示多个 jpeg 图像 例如 假设我有图像 a b c d jpg 每个图像的大小不同 我想将它们绘制在 2x2 网格的一页上 能够为每个子图设置标题也很好 我一直在彻底寻找解决方案 但不知道如何去
  • 如果条件长度 > 1 并且仅使用第一个元素,为什么我会在 R 中收到此警告

    我有下面的源代码 这if is na monthData 用于检查是否monthData is NA 如果是 则为其分配一个初始值 monthData lt NA if category QUARTER for m in c rep 1 4
  • 使用 R 读取和转换二进制原始数据

    我有一个file https drive google com file d 0BxMpk0nhnJy6SFhxd2xuMzJYYlk edit usp sharing其中包含原始 二进制数据和 ascii 它包含一个时间戳和一个代表速度的
  • 获取所有矩阵列逐元素乘积对的快速方法

    假设我有一个数字matrix set seed 1 mat lt matrix rnorm 1000 ncol 100 我想生成所有向量 它们是中所有唯一向量对的逐元素乘积的结果mat 我们如何改进下面的代码 all pairs lt t
  • 确定向量中是否存在元素的最有效方法

    我有几种算法取决于确定元素是否存在于向量中的效率 在我看来 这 in 这相当于is element 应该是最有效的 因为它只返回一个布尔值 在测试了几种方法之后 令我惊讶的是 这些方法是迄今为止效率最低的 以下是我的分析 随着向量大小的增加
  • R 中的转换会导致文档错误

    每当我运行此代码时 tm map 行都会给我警告消息 警告信息 在 tm map SimpleCorpus docs toSpace 中 转换删除文档 texts lt read csv Data fast food Domino s Do
  • 当测试集中不存在响应变量时,h2o 预测有时会失败

    当在不存在响应变量的测试集上进行预测时 如果在训练中对因子变量使用一种热编码 则 h2o 会以各种不同的方式失败 无论是在训练 GLM 时隐式指定还是在其他方法中显式指定时 R 3 4 0 和 h2o 3 12 0 1 中存在此错误 我们还
  • 使用 stargazer 分析包含时间序列的数据帧

    我有一个面板数据集共 10 个观测值和 3 个变量 观测值 30 的数量 10 行 国家 地区 2 列 迁移参数 相应年份的 1 列 可以这么说 我的数据框由 3 个年度数据框组成 我该如何申请观星者考虑到它是一个面板数据集 所以最大 N
  • 对于多项式,获取其所有极值并通过突出显示所有单调部分来绘制它

    有人问我这个有趣的问题 我认为值得将其发布在这里 因为 Stack Overflow 上还没有任何相关线程 假设我有长度为的多项式系数n vector pc 其中次数多项式n 1对于变量x可以以其原始形式表示 pc 1 pc 2 x pc
  • 编写健壮的 R 代码:命名空间、屏蔽和使用 `::` 运算符

    简洁版本 对于那些不想阅读我的 案例 的人来说 这就是本质 最小化新包破坏现有代码 即编写您编写的代码 的机会的推荐方法是什么尽可能坚固 充分利用该功能的推荐方法是什么 命名空间机制 when a just using贡献的软件包 比如在一
  • 使用管道语法处理模型列表

    我经常喜欢拟合和检查与 R 数据框中的两个变量相关的多个模型 我可以使用如下语法来做到这一点 require tidyverse require broom models lt list hp exp cyl hp cyl map df m
  • R:为什么 boxplot(x,log="y") 与 boxplot(log(x)) 不同?

    delme lt exp rnorm 1000 1 5 0 3 boxplot delme log y boxplot log10 delme 为什么这两个图中的胡须不同 谢谢 阿古斯 我想说的是 在您的第一个图中 您只是将 y 轴更改为对
  • R texreg:如何选择要显示的 gof 统计信息?

    我正在使用 texreg 通过 plm 生成面板回归的输出表 我想抑制所有 gof 统计数据的输出 这不是显示 R2 adj R2 和 N 我只想显示 adj R2 有谁知道一个简单的方法来做到这一点 好吧 这实际上很简单 只需在调用中包含
  • Django 中的 Rpy2 错误 - 未为“”类型的对象定义转换“py2rpy”

    我以前从未使用过 R 并且正在尝试使用 rpy2 从 python 调用 R 函数 它可以在独立的 python 终端上运行 但不能在 Django 中运行 但rpy2似乎无法将python字符串转换为r对象 我正在使用同事提供的自定义库
  • 将日期时间字符串转换为 Date 类

    我有一个带有日期时间字符列的数据框 当我使用as Date 除了少数实例之外 我的大多数字符串都被正确解析 下面的示例有望向您展示发生了什么 my attempt to parse the string to Date uses the s
  • matplotlib 中的 R 风格数据轴缓冲区

    R 绘图自动设置 x 和 y 限制 以在数据和轴之间留出一些空间 我想知道 matplotlib 是否有办法自动执行相同的操作 如果没有 是否有一个好的公式或 经验法则 来说明 R 如何设置其轴限制 在 matplotlib 中 您可以通过
  • ggplot 图例标签内的希腊字母、符号和换行符

    我在尝试着 有换行符 自动或强制 对齐文本 左对齐或左右对齐 有希腊字母和百分号 在 gglot 图例标签内 我尝试了几种方法 但我似乎无法将我读到的所有技巧结合起来 我可以通过插入来换行 n进入标签 但这似乎不适用于希腊字母 不适用于图例
  • Android:canvas.drawBitmap() 方法无法正常工作

    我已经发布了两个与此相关的问题 请参考此自定义饼图 1 https stackoverflow com questions 28343600 customize pie chart in quarter shape at the botto
  • R data.table 连接不等式条件

    我想使用 data table 包根据多个不等式条件对数据进行子集化 data table 手册中的示例展示了如何使用字符变量执行此操作 但不显示数字不等式 我还了解了如何使用子集函数来执行此操作 但我真的很想利用 data table 二

随机推荐

  • Spring 批量暂停/恢复与停止/重新启动

    我是 Spring Batch 的新手 有一些关于暂停 恢复的问题 阅读 spring Batch 文档后 似乎没有任何内置的暂停或恢复功能 但是 我从主站点找到了这个用例 http docs spring io spring batch
  • 如何一条一条选择记录而不重复

    select id name from customer order by random limit 5 上述查询选择随机记录 但是它会重复行 我只想每次选择一行而不重复 假设我的 id 为 1 到 5 第一次我想选择 1 第二次查询显示
  • 使用 Azure Active Directory Oauth 进行 Azure 服务管理 API 身份验证

    我想通过curl 使用Azure AD 对Azure 服务管理API 进行身份验证 I 设置一个应用程序在我的默认目录中 在这个免费试用订阅中 这是我拥有的唯一目录 当我定位 oauth 令牌端点时 我收到一个 JWT curl data
  • 关于验证用户登录名和密码的问题

    朋友们 我需要制作一个软件 需要验证有效的用户登录才能使用软件 我试过这个 bool valid false using PrincipalContext context new PrincipalContext ContextType D
  • Docker compose在另一个目录会影响其他容器

    我有一个问题 我用我的docker compose一个项目的文件 然后我将其复制到另一个目录以运行另一个容器 但每当我这样做时 它都会重新创建现有容器 或者如果我使用 down 命令 它还会销毁另一个目录中的容器 可能会出现什么问题 这是我
  • 如何将工作日和时间对象解析为从今天开始的下一个逻辑日期?

    我的字符串中有一个日期 看起来像MON 07 15 我试图将其解析为Date使用这段代码 System out println new SimpleDateFormat E kk mm parse MON 07 15 使用上面的代码 打印一
  • requiredFieldValidator 在更新面板中工作异常

    我有一个带有文本框 必填字段验证器和几个按钮的更新面板 页面加载时 您会看到一个标签和一个按钮 按下按钮时 将显示文本框和验证器 以及其他按钮 显示的基本变化效果很好 但是 即使文本框已填充 我的验证器 设置为动态 也会显示其错误消息 假设
  • 强制 iOS 从 HTML5 Canvas 下载图像(使用纯 JavaScript)

    这个问题之前已经被问过 普遍的回答是在 iOS 上无法完成 However这些问题已经存在了好几年了 有可能已经制定了解决方法 或者现在有办法做到这一点 我有一个可用的纯 JavaScript 图像编辑器 它不会让最后的编辑步骤 保存编辑后
  • 动态高度浏览器

    我正在尝试在自定义滚动视图中创建一个自定义视图分页器 动态包裹当前孩子的高度 package com example vihaan dynamicviewpager import android content Context import
  • Python win32com 和二维数组

    当使用 python 和 win32com 来自动化 Adob e 软件时 会遇到传递 2d 坐标数组的问题 如果看一下 Adob e 为 Visual Basic VB 提供的代码 就会发现很简单 在 Illustrator 中绘制线条的
  • Gorm 关系错误:需要为关系定义有效的外键或者需要实现 Valuer/Scanner 接口

    我正在对使用 Gorm 时出现的问题进行故障排除 我的 sqlite3 数据库和 Go 数据模型一切都工作得很好 但是当我遇到一些依赖项问题时 无法在构建环境中 进入 所以我尝试从供应商文件夹中复制 删除一些包 然后重新 去 直到我让构建工
  • 连接组件

    我有一组数据 是通过将相似的子项目匹配在一起创建的 然后按 类别 对这些相似的项目进行分组 现在 结果类别必须以在每个 group id 内将相关类别分组在一起的方式进行匹配 在下面的示例中 一个匹配是 A gt B gt C gt D g
  • 使用 Windows Phone 7 解析包含数组的 JSON 对象

    好吧 我在这方面遇到了一些困难 我的 JSON 就像 names name bla name bla2 我试图做本教程但是 由于 JSON 不同 它不起作用 我必须在这个方法中放入什么 我不知道创建一个包含我的列表的 包装 类或直接使用 J
  • 仅当文件存在时追加到文件

    我已经看到了几个关于如何附加到文件 如果存在 和创建新文件 如果不存在 的答案 echo hello gt gt file txt 或覆盖文件 如果存在 如果不存在则创建一个文件 echo hello gt file txt 但我如何确保e
  • 预期语句 End If

    我在表单中设置了以下代码 但收到 预期语句 错误 我第一次这样做并认为我的语法正确 我错过了什么 使用嵌套 2 路条件时 每个条件必须由自己的条件结束End If If condition A Th
  • 在define_method中使用局部变量

    我想了解如何define method工作原理以及如何正确使用定义块之外的变量 这是我的代码 class Test def self plugin for i in 1 2 define method test i to sym do p
  • 存储过程获取想要的结果集以提高性能-MYSQL

    我对 mysql 完全陌生 正在努力编写存储过程来获取所需的结果集 正如你所看到的 下面是我的表格 我在用着节点和快车要连接的 APImysql数据库 然后我使用以下命令进行单独查询以获得所需的结果for loop 当我处理数百万条记录时
  • Salesforce对象描述有大数据,如何从Salesforce对象描述中获取有限的数据,例如选项列表值

    我正在寻找获取销售人员对象的字段和选项列表的方法 我可以使用 REAT API 调用来完成此操作 describe在对象名称之后 但有时返回的 JSON 数据非常大 其中有 95 的额外数据是我不想要的 并且带有重复的模式字符串 仅仅为了获
  • 锚标记的 onclick 事件上未定义 Javascript 函数

    我无法访问锚标记的 onclick 事件中的 javascript 函数 在某些情况下它有效 而在某些情况下则无效 任何人都可以说出为什么会发生这种情况吗 HTML 代码 a href class btn waves effect wave
  • ggplot2 饼图和圆环图在同一图上

    I am trying to replicate this with R ggplot I have exactly the same data browsers lt structure list browser structure c