двусторонний график плотности в сочетании с односторонним графиком плотности с выбранными областями в r

# data 
set.seed (123)
xvar <- c(rnorm (1000, 50, 30), rnorm (1000, 40, 10), rnorm (1000, 70, 10))
yvar <-   xvar + rnorm (length (xvar), 0, 20)
myd <- data.frame (xvar, yvar)


# density plot for xvar
            upperp = 80   # upper cutoff
            lowerp = 30   # lower cutoff
            x <- myd$xvar
            plot(density(x))
            dens <- density(x)
            x11 <- min(which(dens$x <= lowerp))
            x12 <- max(which(dens$x <= lowerp))
            x21 <- min(which(dens$x > upperp))
            x22 <- max(which(dens$x > upperp))
            with(dens, polygon(x = c(x[c(x11, x11:x12, x12)]),
                y = c(0, y[x11:x12], 0), col = "green"))
             with(dens, polygon(x = c(x[c(x21, x21:x22, x22)]),
                y = c(0, y[x21:x22], 0), col = "red"))
            abline(v = c(mean(x)), lwd = 2, lty = 2, col = "red")
# density plot with yvar
    upperp = 70  # upper cutoff
    lowerp = 30   # lower cutoff
    x <- myd$yvar
    plot(density(x))
    dens <- density(x)
    x11 <- min(which(dens$x <= lowerp))
    x12 <- max(which(dens$x <= lowerp))
    x21 <- min(which(dens$x > upperp))
    x22 <- max(which(dens$x > upperp))
    with(dens, polygon(x = c(x[c(x11, x11:x12, x12)]),
        y = c(0, y[x11:x12], 0), col = "green"))
     with(dens, polygon(x = c(x[c(x21, x21:x22, x22)]),
        y = c(0, y[x21:x22], 0), col = "red"))
    abline(v = c(mean(x)), lwd = 2, lty = 2, col = "red")

Мне нужно построить двухсторонний график плотности, я не уверен, что есть лучший способ, чем следующий:

ggplot(myd,aes(x=xvar,y=yvar))+
    stat_density2d(aes(fill=..level..), geom="polygon") +
    scale_fill_gradient(low="blue", high="green") + theme_bw()

Я хочу объединить все три типа в один (я не знал, могу ли я создать двухсторонний график в ggplot), нет предпочтения относительно того, будет ли решение графиков в ggplot, базовым или смешанным. Я надеюсь, что это выполнимый проект, учитывая надежность R. Я лично предпочитаю ggplot2.

введите описание изображения здесь

Примечание: нижняя штриховка на этом графике неправильная, красный всегда должен быть нижним, а зеленый верхний на графиках xvar и yvar, что соответствует заштрихованной области на графике плотности xy.

Изменить: Максимальное ожидание на графике (спасибо Seth и jon за очень подробный ответ) (1) удаление меток пробела и осей и т. д., чтобы сделать его компактным
(2) выравнивание сеток так, чтобы середина метки и сетки на графике должны совпадать с боковыми метками и метками, а размер графиков должен быть одинаковым. введите описание изображения здесь


person SHRram    schedule 18.07.2012    source источник
comment
Ответ здесь может помочь с получением плотностей с помощью ggplot stackoverflow.com/questions/8545035/   -  person Seth    schedule 18.07.2012
comment
Ваш вопрос очень вдохновляет, и мне интересно, не могли бы вы поделиться окончательными кодами, которые могут отобразить фигуру в своем сообщении? Большое спасибо.   -  person Yang Yang    schedule 22.09.2017


Ответы (3)


Вот пример объединения нескольких графиков с выравниванием:

library(ggplot2)
library(grid)

set.seed (123)
xvar <- c(rnorm (100, 50, 30), rnorm (100, 40, 10), rnorm (100, 70, 10))
yvar <-   xvar + rnorm (length (xvar), 0, 20)
myd <- data.frame (xvar, yvar)

p1 <- ggplot(myd,aes(x=xvar,y=yvar))+
  stat_density2d(aes(fill=..level..), geom="polygon") +
  coord_cartesian(c(0, 150), c(0, 150)) +
  opts(legend.position = "none")

p2 <- ggplot(myd, aes(x = xvar)) + stat_density() +
  coord_cartesian(c(0, 150))
p3 <- ggplot(myd, aes(x = yvar)) + stat_density() + 
  coord_flip(c(0, 150))

gt <- ggplot_gtable(ggplot_build(p1))
gt2 <- ggplot_gtable(ggplot_build(p2))
gt3 <- ggplot_gtable(ggplot_build(p3))

gt1 <- ggplot2:::gtable_add_cols(gt, unit(0.3, "null"), pos = -1)
gt1 <- ggplot2:::gtable_add_rows(gt1, unit(0.3, "null"), pos = 0)

gt1 <- ggplot2:::gtable_add_grob(gt1, gt2$grobs[[which(gt2$layout$name == "panel")]],
                                  1, 4, 1, 4)
gt1 <- ggplot2:::gtable_add_grob(gt1, gt2$grobs[[which(gt2$layout$name == "axis-l")]],
                                 1, 3, 1, 3, clip = "off")

gt1 <- ggplot2:::gtable_add_grob(gt1, gt3$grobs[[which(gt3$layout$name == "panel")]],
                                 4, 6, 4, 6)
gt1 <- ggplot2:::gtable_add_grob(gt1, gt3$grobs[[which(gt3$layout$name == "axis-b")]],
                                 5, 6, 5, 6, clip = "off")
grid.newpage()
grid.draw(gt1)

введите описание изображения здесь

обратите внимание, что это работает с gglot2 0.9.1, и в будущем выпуске вам будет проще это сделать.

И наконец

вы можете сделать это:

library(ggplot2)
library(grid)

set.seed (123)
xvar <- c(rnorm (100, 50, 30), rnorm (100, 40, 10), rnorm (100, 70, 10))
yvar <-   xvar + rnorm (length (xvar), 0, 20)
myd <- data.frame (xvar, yvar)

p1 <- ggplot(myd,aes(x=xvar,y=yvar))+
  stat_density2d(aes(fill=..level..), geom="polygon") +
  geom_polygon(aes(x, y), 
               data.frame(x = c(-Inf, -Inf, 30, 30), y = c(-Inf, 30, 30, -Inf)),
               alpha = 0.5, colour = NA, fill = "red") +
  geom_polygon(aes(x, y), 
               data.frame(x = c(Inf, Inf, 80, 80), y = c(Inf, 80, 80, Inf)),
               alpha = 0.5, colour = NA, fill = "green") +
  coord_cartesian(c(0, 120), c(0, 120)) +
  opts(legend.position = "none")

xd <- data.frame(density(myd$xvar)[c("x", "y")])
p2 <- ggplot(xd, aes(x, y)) + 
  geom_area(data = subset(xd, x < 30), fill = "red") +
  geom_area(data = subset(xd, x > 80), fill = "green") +
  geom_line() +
  coord_cartesian(c(0, 120))

yd <- data.frame(density(myd$yvar)[c("x", "y")])
p3 <- ggplot(yd, aes(x, y)) + 
  geom_area(data = subset(yd, x < 30), fill = "red") +
  geom_area(data = subset(yd, x > 80), fill = "green") +
  geom_line() +
  coord_flip(c(0, 120))

gt <- ggplot_gtable(ggplot_build(p1))
gt2 <- ggplot_gtable(ggplot_build(p2))
gt3 <- ggplot_gtable(ggplot_build(p3))

gt1 <- ggplot2:::gtable_add_cols(gt, unit(0.3, "null"), pos = -1)
gt1 <- ggplot2:::gtable_add_rows(gt1, unit(0.3, "null"), pos = 0)

gt1 <- ggplot2:::gtable_add_grob(gt1, gt2$grobs[[which(gt2$layout$name == "panel")]],
                                  1, 4, 1, 4)
gt1 <- ggplot2:::gtable_add_grob(gt1, gt2$grobs[[which(gt2$layout$name == "axis-l")]],
                                 1, 3, 1, 3, clip = "off")

gt1 <- ggplot2:::gtable_add_grob(gt1, gt3$grobs[[which(gt3$layout$name == "panel")]],
                                 4, 6, 4, 6)
gt1 <- ggplot2:::gtable_add_grob(gt1, gt3$grobs[[which(gt3$layout$name == "axis-b")]],
                                 5, 6, 5, 6, clip = "off")
grid.newpage()
grid.draw(gt1)

введите описание изображения здесь

person kohske    schedule 21.07.2012

Как и в приведенном выше примере, вам понадобится пакет gridExtra. Это то, что вы дали.

g=ggplot(myd,aes(x=xvar,y=yvar))+
    stat_density2d(aes(fill=..level..), geom="polygon") +
    scale_fill_gradient(low="blue", high="green") + theme_bw()

используйте geom_rect, чтобы нарисовать две области

gbig=g+geom_rect(data=myd,
        aes(  NULL,
            NULL,
            xmin=0,
            xmax=lowerp,
            ymin=-10,
            ymax=20),
        fill='red',
        alpha=.0051,
        inherit.aes=F)+
  geom_rect(aes(    NULL,
            NULL,
            xmin=upperp,
            xmax=100,
            ymin=upperp,
            ymax=130),
            fill='green',
            alpha=.0051,
            inherit.aes=F)+
  opts(legend.position = "none") 

Это простая гистограмма ggplot; в нем отсутствуют ваши цветные регионы, но они довольно легкие

  dens_top <- ggplot()+geom_density(aes(x))
  dens_right <- ggplot()+geom_density(aes(x))+coord_flip()

Сделайте пустой график, чтобы заполнить угол

  empty <- ggplot()+geom_point(aes(1,1), colour="white")+
              opts(axis.ticks=theme_blank(), 
                   panel.background=theme_blank(), 
                   axis.text.x=theme_blank(), 
                   axis.text.y=theme_blank(),           
                   axis.title.x=theme_blank(), 
                   axis.title.y=theme_blank())

Затем используйте функцию grid.arrange:

library(gridExtra)

grid.arrange(dens_top,     empty     , 
             gbig,         dens_right, 
                 ncol=2, 
                 nrow=2, 
                 widths=c(4, 1), 
                 heights=c(1, 4))

введите описание изображения здесь

Не очень красиво, но идея есть. Вам также нужно будет убедиться, что весы совпадают!

person Seth    schedule 18.07.2012
comment
Спасибо за ответ Сет, это действительно шаг вперед ... Возможно, мне все еще нужно поработать над закрашиванием областей на графиках плотности марингема (красный и зеленый) и отображением средних линий. Также удалите lebel оси x на графиках плотности и сделайте графики компактными. - person SHRram; 19.07.2012
comment
Наиболее важным является масштаб xvar и yvar на всех графиках, которые необходимо согласовать ... - person SHRram; 19.07.2012
comment
этот вопрос касается установления лимитов. stackoverflow.com/questions/3606697/ - person Seth; 19.07.2012

Основываясь на ответе Сета (спасибо, Сет, и вы заслуживаете всех благодарностей), я улучшил некоторые вопросы, поднятые вопрошающим. Поскольку комментарии слишком короткие, чтобы ответить на все вопросы, я предпочитаю использовать его как ответ. Есть еще пара проблем, нужна ваша помощь:

# data
set.seed (123)
xvar <- c(rnorm (1000, 50, 30), rnorm (1000, 40, 10), rnorm (1000, 70, 10))
yvar <-   xvar + rnorm (length (xvar), 0, 20)
myd <- data.frame (xvar, yvar)

require(ggplot2)

# density plot for xvar
upperp = 80   # upper cutoff
lowerp = 30

средняя фигура

 g=ggplot(myd,aes(x=xvar,y=yvar))+
    stat_density2d(aes(fill=..level..), geom="polygon") +
    scale_fill_gradient(low="blue", high="green") + 
  scale_x_continuous(limits = c(0, 110)) + 
   scale_y_continuous(limits = c(0, 110)) + theme_bw()

geom_rect два региона

gbig=g+ geom_rect(data=myd, aes(  NULL,  NULL, xmin=0,  
xmax=lowerp,ymin=0, ymax=20), fill='red', alpha=.0051,inherit.aes=F)+ 
geom_rect(aes(NULL,  NULL,   xmin=upperp,            xmax=110, 
 ymin=upperp,            ymax=110),            fill='green',            
  alpha=.0051,
            inherit.aes=F)+   
  opts(legend.position = "none", 
  plot.margin = unit(rep(0, 4), "lines"))

Верхняя гистограмма с заштрихованной областью

    x.dens <- density(myd$xvar)
    df.dens <- data.frame(x = x.dens$x, y = x.dens$y)

   dens_top <- ggplot()+geom_density(aes(myd$xvar, y = ..density..))
+ scale_x_continuous(limits = c(0, 110)) +
geom_area(data = subset(df.dens, x <= lowerp), aes(x=x,y=y), fill = 'red') 
 +  geom_area(data = subset(df.dens, x >= upperp), aes(x=x,y=y), fill = 'green') 
 +    opts (axis.text.x=theme_blank(), axis.title.x=theme_blank(), 
  plot.margin = unit(rep(0, 4), "lines")) + xlab ("") + ylab ("") +  theme_bw()

правая гистограмма с заштрихованной областью

   y.dens <- density(myd$yvar)
    df.dens.y <- data.frame(x = y.dens$x, y = y.dens$y)

    dens_right <- ggplot()+geom_density(aes(myd$yvar, y = ..density..))
   + scale_x_continuous(limits = c(0, 110)) +
  geom_area(data = subset(df.dens.y, x <= lowerp), aes(x=x,y=y), 
  fill = 'red') 
  +  geom_area(data = subset(df.dens.y, x >= upperp), aes(x=x,y=y), 
  fill = 'green')
    +      coord_flip() + 


opts (axis.text.x=theme_blank(), axis.title.x=theme_blank(), 
   plot.margin = unit(rep(0, 4), "lines")) + xlab ("") + ylab ("") 
   +  theme_bw()

Сделайте пустой график, чтобы заполнить угол

       empty <- ggplot()+geom_point(aes(1,1), colour="white")+ 
       scale_x_continuous(breaks = NA) + scale_y_continuous(breaks = NA) +
              opts(axis.ticks=theme_blank(),
                   panel.background=theme_blank(),
                   axis.text.x=theme_blank(),
                   axis.text.y=theme_blank(),
                   axis.title.x=theme_blank(),
                   axis.title.y=theme_blank())

Затем используйте функцию grid.arrange:

library(gridExtra)
 grid.arrange(dens_top, empty , gbig, dens_right, ncol=2,nrow=2,
 widths=c(2, 1), heights=c(1, 2))

введите описание изображения здесь

PS: (1) Может ли кто-нибудь помочь идеально выровнять графики? (2) Может ли кто-нибудь помочь удалить дополнительное пространство между графиками, я попытался отрегулировать поля, но между графиком плотности x и y и центральным графиком есть пробел.

person jon    schedule 19.07.2012
comment
спасибо, между заполненной областью и линией плотности вроде бы есть разрыв, есть ли способ его улучшить? - person SHRram; 19.07.2012