jjzjj

ggplot2优雅的绘制饼状热图

R语言数据分析指南 2023-03-28 原文

欢迎关注R语言数据分析指南

最近看到一张非常有意思的图,暂且称之为饼状热图,与corrplot所绘制的有所不同此图使用的为离散型变量,例图如下所展示;由于作者未提供原始数据,小编自己构建了一份数据来进行初步的展示

论文内容

Systematic profiling of the chicken gut microbiome reveals dietary supplementation with antibiotics alters expression of multiple microbial pathways with minimal impact on community structure

此图乍一看觉得似曾相识,但是仔细一看又会发现好像不是那么的容易;应该是没有现成的包来一步出图,由于作者也未有提供数据那只有靠猜数据结构来进行可视化了,细节当然是很多,小编这次只是绘制主体图,细节问题留待以后再做介绍

加载R包

library(tidyverse)
library(scatterpie)
library(ggsci)
library(cowplot)

数据清洗

p <- read_tsv("data1.txt") %>% 
  filter(Compartments %in% c("BS","RS","RE","VE","SE","LE")) %>% 
  select(1,2,Compartments) %>% 
  left_join(.,read_tsv("data2.txt") %>% column_to_rownames(var="FAPROTAX") %>% t() %>% 
              as.data.frame() %>%
              rownames_to_column(var="Compartments") %>% 
              pivot_longer(-Compartments),by="Compartments") %>% 
  filter(Compartments=="BS",
         SampleID %in% c(read_tsv("data1.txt") %>% select(1) %>% 
                           distinct() %>% head(10) %>% pull())) %>% 
  select(-value,-Compartments) %>% 
  group_by(SampleID,name) %>% count(Phylum) %>% 
  pivot_wider(.,names_from=Phylum,values_from = n)

构建绘图数据

df <- p %>% left_join(.,p %>% select(name) %>% distinct() %>% rownames_to_column(var="lat"),by="name") %>% 
  mutate(long=case_when(SampleID =="BCCCK1" ~1,SampleID =="BCCCK2" ~2,SampleID =="BCCCK3" ~3,
                        SampleID =="BCCNPK1" ~4,SampleID =="BCCNPK2" ~5,SampleID =="BCCNPK3" ~6,
                        SampleID =="BCCNPKM1" ~7,SampleID =="BCCNPKM2" ~8,SampleID =="BCCNPKM3" ~9,
                        SampleID =="BHLCK1" ~10),lat=as.numeric(lat))

绘制饼状热图

p1 <- ggplot(aes(x=long,y=lat),data=df) +
  geom_tile(color="black",fill="white")+
  geom_scatterpie(aes(x=long,y=lat,r=0.4),data=df, color=NA,
                           cols=c("Abditibacteriota","Acidobacteriota","Actinobacteriota",
                                  "Alphaproteobacteria","Bacteroidota")) +
                             coord_equal()+
  scale_fill_brewer()+
  scale_x_discrete(expand = c(0,0))+
  scale_y_discrete(expand = c(0,0))+
  theme_test()+
  theme(axis.text.x=element_text(angle = 90,vjust = 0.5,hjust = 1),
        axis.ticks = element_blank(),
        axis.text.y=element_blank(),
        axis.title = element_blank(),
        legend.title = element_blank(),
        legend.key=element_blank(),   # 图例键为空
        legend.text = element_text(color="black",size=9), # 定义图例文本
        legend.spacing.x=unit(0.1,'cm'), # 定义文本书平距离
        legend.key.width=unit(0.5,'cm'), # 定义图例水平大小
        legend.key.height=unit(0.5,'cm'), # 定义图例垂直大小
        legend.background=element_blank())

绘制文本

p2 <- df %>% select(name,lat) %>% arrange(lat) %>% mutate(type="A") %>% 
  ggplot(aes(type,name))+
  coord_cartesian(clip="off")+
  scale_x_discrete(expand = c(0,0))+
#  scale_y_discrete(expand = c(0,0))+
  theme(panel.background = element_rect(fill="white"),
        axis.ticks = element_blank(),
        axis.text.y=element_text(color="black"),
        axis.title=element_blank(),axis.text.x=element_blank())

拼图

ggdraw(xlim=c(-0.45,1))+ 
  draw_plot(p2,x=-0.4)+
  draw_plot(p1,x=0.06)

有关ggplot2优雅的绘制饼状热图的更多相关文章

  1. ruby-on-rails - Rails 优雅地处理超时 session ? - 2

    使用rails4,ruby2。我在rails配置中为我的cookiesession设置了30分钟的超时时间。问题是,如果我转到表单,让session超时,然后提交表单,我会收到此ActionController::InvalidAuthenticityToken错误。如何在Rails中优雅地处理这个错误?比如说,重定向到登录屏幕? 最佳答案 在您的ApplicationController:rescue_fromActionController::InvalidAuthenticityTokendoredirect_tosome_p

  2. ruby - 获取数组中的值并最小化某个类属性的最优雅的方法是什么? - 2

    假设我有以下类(class):classPersondefinitialize(name,age)@name=name@age=ageenddefget_agereturn@ageendend我有一组Person对象。是否有一种简洁的、类似于Ruby的方法来获取最小(或最大)年龄的人?如何根据它对它们进行排序? 最佳答案 这样做会:people_array.min_by(&:get_age)people_array.max_by(&:get_age)people_array.sort_by(&:get_age)

  3. ruby-on-rails - 优雅的 Rails : multiple routes, 相同的 Controller Action - 2

    让多条路线去同一条路的最优雅的方式是什么ControllerAction?我有:get'dashboard',to:'dashboard#index'get'dashboard/pending',to:'dashboard#index'get'dashboard/live',to:'dashboard#index'get'dashboard/sold',to:'dashboard#index'这很丑陋。有什么“更优雅”的建议吗?一个类轮的奖励积分。 最佳答案 为什么不只有一个路由和一个Controller操作,并根据传递给它的参数来

  4. ruby - 鸭子输入字符串、符号和数组的优雅方式? - 2

    这是针对我无法破坏的现有公共(public)API,但我确实希望对其进行扩展。目前,该方法采用字符串或符号或任何其他在作为第一个参数传递给send时有意义的内容我想添加发送字符串、符号等列表的功能。我可以只使用is_a吗?数组,但还有其他发送列表的方法,这不是很像ruby​​。我将调用列表中的map,所以第一个倾向是使用respond_to?:map。但是字符串也会响应:map,所以这行不通。 最佳答案 如何将它们全部视为数组?String的行为与仅包含String的Array相同:deffoo(obj,arg)[*arg].eac

  5. ruby - 优雅的链式 'or' 用于测试 Ruby 中的相同变量 - 2

    怎样说才是明智的呢?if@thing=="01"or"02"or"03"or"04"or"05"(数字包含在数据类型字符串的列中。) 最佳答案 制作数组并使用.include?if["01","02","03","04","05"].include?(@thing)如果值真的都是连续的,你可以使用像(1..5).include?这样的范围对于字符串,你可以使用:if("01".."05").include?(@thing) 关于ruby-优雅的链式'or'用于测试Ruby中的相同变量,我

  6. ruby - Ruby 中优雅的循环 Elsing - 2

    我必须编写一个Ruby方法:遍历数组,如果其中一个元素符合特定条件则执行Foo。如果没有数组元素符合条件,则执行Bar操作。在任何其他语言中,我会在进入循环之前设置一个bool变量,并在执行Foo时切换它。该变量的值会告诉我是否需要Bar。但这感觉不像Rubyish那样不优雅。谁能提出更好的方法?编辑一些非常好的答案,但由于我本应提及的细节,它们不太有效。Foo所做的事情是对符合条件的数组元素完成的。此外,保证最多有一个元素匹配条件。 最佳答案 是否有任何项目匹配?如果是,则做一些不涉及匹配项目的事情。ifitems.any?{|i

  7. ruby - 在 ruby​​ 中对范围进行排序的最优雅的方法是什么 - 2

    我需要根据起点对Range类型的对象表进行排序。为此,我有以下代码可以正常工作:ranges=@ranges.sortdo|a,b|(a.min)(b.min)end我只是想知道是否有更短、更优雅的方法来做同样的事情。 最佳答案 怎么样:ranges=@ranges.sort_by(&:min)或者如果您实际上指的是起点而不是最小值,因为可能存在诸如(5..3)的范围:ranges=@ranges.sort_by(&:first) 关于ruby-在ruby​​中对范围进行排序的最优雅的方

  8. ruby-on-rails - 优雅地处理嵌套哈希中的空白值 - 2

    这个问题在这里已经有了答案:HowtoavoidNoMethodErrorformissingelementsinnestedhashes,withoutrepeatednilchecks?(16个答案)关闭7年前。我确定我以前见过一个优雅的解决方案,但我找不到它:我有一个RailsController,它可能有也可能没有以下哈希元素:myhash[:parent_field]在该父字段中,子元素也可以为空。我目前正在通过(非常丑陋的)方法检查:if(!myhash[:parent_field]||!myhash[:parent_field][:child_field]||myhash

  9. Ruby:Ruby 中优雅的数组初始化和返回 - 2

    我有一个方法:defdeltas_to_board_locations(deltas,x,y)board_coords=[]deltas.each_slice(2)do|slice|board_coords其中deltas是一个数组,x,y是fixnums。有没有办法去掉第一行和最后一行,让方法更优雅?喜欢:defdeltas_to_board_locations(deltas,x,y)deltas.each_slice(2)do|slice|board_coords 最佳答案 deltas.each_slice(2).flat_m

  10. ruby - 优雅的 ruby 单衬垫 - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我如此喜欢用Ruby编写的原因之一是因为它非常有能力通过一个代码实现很多。我喜欢:@sentence=@sentence.split('').map!{|x|x=x[0..0].upcase它把每个单词的第一个字母大写,这不是最惊人的,但相当有效。您见过或用Ruby写过的最优雅的代码是什么?

随机推荐