在r中与图形对齐

jon*_*jon 22 r photo ggplot2

首先我认为我需要在powerpoint中手动操作,然后我想如果有解决方案可以尝试使用R. 这是我的示例数据:

set.seed(123)
myd<- expand.grid('cat' = LETTERS[1:5], 'cond'= c(F,T), 'phase' = c("Interphase", "Prophase", "Metaphase", "Anaphase", "Telophase"))
myd$value <- floor((rnorm(nrow(myd)))*100)
myd$value[myd$value < 0] <- 0

require(ggplot2)
ggplot() +
  geom_bar(data=myd, aes(y = value, x = phase, fill = cat), stat="identity",position='dodge') +
  theme_bw()
Run Code Online (Sandbox Code Playgroud)

这是输出应该是什么样子: 在此输入图像描述

jpeg图像可以随机生成(演示示例)或链接上的示例图:

间期 前期,中期,后期,末期

编辑:

建议@bapste

在此输入图像描述

bap*_*ste 14

您可以为其创建自定义元素函数axis.text.x,但它非常繁琐且复杂.过去也提出过类似的要求,为这个和其他自定义更改(条带标签,轴等)提供一个干净的解决方案将很高兴.功能请求,任何人?

在此输入图像描述

library(jpeg)
img <- lapply(list.files(pattern="jpg"), readJPEG )
names(img) <- c("Anaphase", "Interphase", "Metaphase", "Prophase", "Telophase")

require(ggplot2)
require(grid)

# user-level interface to the element grob
my_axis = function(img) {
    structure(
      list(img=img),
      class = c("element_custom","element_blank", "element") # inheritance test workaround
    )
  }
# returns a gTree with two children: the text label, and a rasterGrob below
element_grob.element_custom <- function(element, x,...)  {
  stopifnot(length(x) == length(element$img))
  tag <- names(element$img)
  # add vertical padding to leave space
  g1 <- textGrob(paste0(tag, "\n\n\n\n\n"), x=x,vjust=0.6)
  g2 <- mapply(rasterGrob, x=x, image = element$img[tag], 
               MoreArgs = list(vjust=0.7,interpolate=FALSE,
                               height=unit(5,"lines")),
               SIMPLIFY = FALSE)

  gTree(children=do.call(gList,c(g2,list(g1))), cl = "custom_axis")
}
# gTrees don't know their size and ggplot would squash it, so give it room
grobHeight.custom_axis = heightDetails.custom_axis = function(x, ...)
  unit(6, "lines")

ggplot(myd) +
  geom_bar(aes(y = value, x = phase, fill = cat), stat="identity", position='dodge') +
  theme_bw() +
  theme(axis.text.x = my_axis(img),
          axis.title.x = element_blank())

ggsave("test.png",p,width=10,height=8)
Run Code Online (Sandbox Code Playgroud)


ags*_*udy 12

使用grid包,并使用视口,你可以拥有它

在此输入图像描述

## transform the jpeg to raster grobs
library(jpeg)
names.axis <-  c("Interphase", "Prophase", "Metaphase", "Anaphase", "Telophase")
images <- lapply(names.axis,function(x){
  img <- readJPEG(paste('lily_',x,'.jpg',sep=''), native=TRUE)
  img <- rasterGrob(img, interpolate=TRUE)
  img
  } )
## main viewports, I divide the scene in 10 rows ans 5 columns(5 pictures)
pushViewport(plotViewport(margins = c(1,1,1,1),
             layout=grid.layout(nrow=10, ncol=5),xscale =c(1,5)))
## I put in the 1:7 rows the plot without axis
## I define my nested viewport then I plot it as a grob.
pushViewport(plotViewport(layout.pos.col=1:5, layout.pos.row=1:7,
             margins = c(1,1,1,1)))
pp <- ggplot() +
  geom_bar(data=myd, aes(y = value, x = phase, fill = cat), 
                 stat="identity",position='dodge') +
  theme_bw()+theme(legend.position="none", axis.title.y=element_blank(),
                   axis.title.x=element_blank(),axis.text.x=element_blank())
gg <- ggplotGrob(pp)
grid.draw(gg)
upViewport()
## I draw my pictures in between rows 8/9 ( visual choice)
## I define a nested Viewport for each picture than I draw it.
sapply(1:5,function(x){
  pushViewport(viewport(layout.pos.col=x, layout.pos.row=8:9,just=c('top')))
  pushViewport(plotViewport(margins = c(5.2,3,4,3)))
  grid.draw(images[[x]])
  upViewport(2)
  ## I do same thing for text 
  pushViewport(viewport(layout.pos.col=x, layout.pos.row=10,just=c('top')))
  pushViewport(plotViewport(margins = c(1,3,1,1)))
    grid.text(names.axis[x],gp = gpar(cex=1.5))
  upViewport(2)
})
pushViewport(plotViewport(layout.pos.col=1:5, layout.pos.row=1:9,
             margins = c(1,1,1,1)))
grid.rect(gp=gpar(fill=NA))
upViewport(2)
Run Code Online (Sandbox Code Playgroud)

  • @SHRram我用虚拟的图像列表更新了我的答案.由于您操作了2个列表(images和names.axis),因此顺序很经典 (3认同)
  • @jon肯定是的!你需要玩边距!我改变了 我认为现在看起来不错. (2认同)

Cla*_*lke 7

产生这样一个数字已经成为在cowplot包可用功能相对简单,特别是axis_canvas()insert_xaxis_grob()功能.(免责声明:我是包裹作者.)

require(cowplot)

# create the data
set.seed(123)
myd <- expand.grid('cat' = LETTERS[1:5], 'cond'= c(F,T), 'phase' = c("Interphase", "Prophase", "Metaphase", "Anaphase", "Telophase"))
myd$value <- floor((rnorm(nrow(myd)))*100)
myd$value[myd$value < 0] <- 0

# make the barplot
pbar <- ggplot(myd) +
  geom_bar(aes(y = value, x = phase, fill = cat), stat="identity", position='dodge') +
  scale_y_continuous(limits = c(0, 224), expand = c(0, 0)) +
  theme_minimal(14) +
  theme(axis.ticks.length = unit(0, "in"))

# make the image strip
pimage <- axis_canvas(pbar, axis = 'x') + 
  draw_image("http://www.microbehunter.com/wp/wp-content/uploads/2009/lily_interphase.jpg", x = 0.5, scale = 0.9) +
  draw_image("http://www.microbehunter.com/wp/wp-content/uploads/2009/lily_prophase.jpg", x = 1.5, scale = 0.9) +
  draw_image("http://www.microbehunter.com/wp/wp-content/uploads/2009/lily_metaphase2.jpg", x = 2.5, scale = 0.9) +
  draw_image("http://www.microbehunter.com/wp/wp-content/uploads/2009/lily_anaphase2.jpg", x = 3.5, scale = 0.9) +
  draw_image("http://www.microbehunter.com/wp/wp-content/uploads/2009/lily_telophase.jpg", x = 4.5, scale = 0.9)

# insert the image strip into the bar plot and draw  
ggdraw(insert_xaxis_grob(pbar, pimage, position = "bottom"))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我在这里直接从网上阅读图像,但该draw_image()功能也适用于本地文件.

从理论上讲,应该可以使用geom_image()ggimage包来绘制图像条,但是如果没有扭曲的图像我就无法工作,所以我使用了五个draw_image()调用.


Cla*_*lke 5

编辑:这是一个很容易破解的繁琐方法.请考虑使用此解决方案.

这是使用cowplot包的解决方案.它不一定更好,因为它需要一些摆弄坐标来正确排列,但它是一种替代方案,它在某些方面可能更灵活.

在此输入图像描述

# create data
set.seed(123)
myd<- expand.grid('cat' = LETTERS[1:5], 'cond'= c(F,T), 'phase' = c("Interphase", "Prophase", "Metaphase", "Anaphase", "Telophase"))
myd$value <- floor((rnorm(nrow(myd)))*100)
myd$value[myd$value < 0] <- 0

# load images
library(jpeg)
img <- lapply(list.files(pattern="jpg"), readJPEG )
names(img) <- c("Anaphase", "Interphase", "Metaphase", "Prophase", "Telophase")

# solution via cowplot, define a function that draws a strip of images
require(cowplot)
add_image_strip <- function(plot, image_list, xmin = 0, xmax = 1, y = 0, height = 1)
{
    xstep = (xmax-xmin)/length(image_list)
    for (img in image_list)
    {
        g <- grid::rasterGrob(img, interpolate=TRUE)
        plot <- plot + annotation_custom(g, xmin, xmax = xmin + xstep, ymin = y, ymax = y + height)
        xmin <- xmin + xstep
    }
    plot
}

# make the bar plot, with extra spacing at the bottom
plot.myd <- ggplot(myd) +
  geom_bar(aes(y = value, x = phase, fill = cat), stat="identity", position='dodge') +
  theme( axis.title.x = element_blank(),
         plot.margin = unit(c(1, 1, 4.5, 0.5), "lines")
        )

# place bar plot and image strip onto blanc canvas
# requires some fiddling with numbers, specific choice depends
# on `width` and `height` choices in ggsave 
plot <- ggdraw(plot.myd)
plot <- add_image_strip(plot, image_list=img, xmin = .105, xmax = 0.875, y=.04, height = .18)
ggsave("test.png", plot, width=8, height=4)
Run Code Online (Sandbox Code Playgroud)