R:grid.arrange边缘图到ggplot2“heatmap”(geom_tile)

时间:2016-08-09 16:44:11

标签: r ggplot2

我想在热图的顶部和右侧添加两个条形图,表示热图所代表的双变量分布的两个维度上的边际分布。

以下是一些代码:

public class HomeActivity extends BaseActivity {

private Button mButton;
SharedPreferences prefs;
Context mContext;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_all_layout);
    activateToolbar();
    setUpNavigationDrawer();
    getSupportActionBar().setTitle("Shieko Workout");

    prefs = getApplicationContext().getSharedPreferences("checkstate", Context.MODE_PRIVATE);

    mButton = (Button) findViewById(R.id.button2);

    mButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            prefs.edit().remove("checkstate");
            prefs.edit().commit();
            Toast.makeText(getApplicationContext(), "Checkboxes Cleared.", Toast.LENGTH_LONG).show();
        }
    });
}
}

产生这个: enter image description here

我想要做的是将图形移动到红色箭头所示的对齐位置: - (1,1)的y轴应与(2,1)的y轴对齐 - (2,1)的x轴应与(2,2)

的x轴对齐

2 个答案:

答案 0 :(得分:3)

gtable非常有用。 scales提供了用于格式化轴刻度的工具,通过格式化前者来实现热图(X,F,...)的文本y.ticks与顶部条形图的数字y.ticks之间的对齐。固定宽度为5个字符(适合您的特定情节)。

require(ggplot2)
require(gtable)
require(grid)
library(dplyr)
library(scales)


## To format heatmap y.ticks with appropriate width (5 chars),
## to align with gg_rows y.tics
ytickform <- function(x){
    lab <- sprintf("%05s",x)
}

set.seed(123)
## generate some data
df_hm = cbind(
  expand.grid(
    rows = sample(letters, 10), 
    cols = sample(LETTERS, 10)
  ), 
  value = rnorm(100)
)

# plot the heatmap
gg_hm = df_hm %>% 
    ggplot(aes(x = rows, y = cols, fill = value)) + 
    geom_tile() + 
    scale_y_discrete(label=ytickform) +
    theme(legend.position = "bottom",
          plot.margin = unit(c(3,3,3,3), "mm"))

gg_rows = df_hm %>% 
    group_by(rows) %>% 
    summarize(value = mean(value)) %>% 
    ggplot(aes(x = rows,y = value)) + 
    geom_bar(stat = "identity", position = "dodge") +
    theme(plot.margin = unit(c(3,3,3,3), "mm"))


gg_cols = df_hm %>% 
    group_by(cols) %>% 
    summarize(value = mean(value)) %>% 
    ggplot(aes(x = cols, y = value))+ 
    geom_bar(stat = "identity", position = "dodge") + 
    coord_flip() +
    theme(plot.margin = unit(c(3,3,3,3), "mm"))

## extract legend from heatmap
g <- ggplotGrob(gg_hm)$grobs
legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]]

## plot heatmap without legend
g <- ggplotGrob(gg_hm + theme(legend.position="none"))

## add column and put column barplot within
g <- gtable_add_cols(g, unit(5,"cm"))
g <- gtable_add_grob(g, ggplotGrob(gg_cols), 
                     t = 1, l=ncol(g), b=nrow(g), r=ncol(g))

## add row and put legend within
g <- gtable_add_rows(g, unit(1,"cm"))
g <- gtable_add_grob(g, legend, 
                     t = nrow(g), l=1, b=nrow(g), r=ncol(g)-1)

## add row on top and put row barplot within
g <- gtable_add_rows(g, unit(5,"cm"), 0)
g <- gtable_add_grob(g, ggplotGrob(gg_rows),
                     t = 1, l=1, b=1, r=5) 

grid.newpage()
grid.draw(g)

参考文献:

Align ggplot2 plots vertically

http://www.cookbook-r.com/Graphs/Axes_(ggplot2)/#tick-mark-label-text-formatters

https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs

答案 1 :(得分:2)

我尝试了 renato vitolo 接受的答案,并且对齐在我的机器上无效。但我后来发现了一个更简单的解决方案:egg包(在CRAN上可用)。 egg提供了一个名为grid.arrange的{​​{1}}版本,它采用了类似的参数,但很好地对齐了这些轴。在OP的代码中,我只需添加ggarrangelibrary(egg),然后将library(dplyr)替换为grid.arrange(已安装ggarrange egg) 。

完整代码:

install.packages("egg")

输出:

Output