ggplot2で描いたヒートマップをラスター画像で出力する

heatmap
ggplot2
R
Published

February 18, 2024

TL;DR

ggplot2で作図したセル数が多いヒートマップをラスター画像で出力する時は、 geom_tileではなくgeom_rasterを使う。

Load packages

library(magrittr)
library(ggplot2)

動機

ggplot2で作図したセル数が多いヒートマップをラスター画像で出力する際に、 geom_tileで作図して出力すると、セルが細かい場合に正確に描画できずに色味が変わってしまった。

作図

ヒートマップ用データの作成

set.seed(123)
tbl_plot <-
  matrix(rnorm(20000), ncol = 10) %>%
  tibble::as_tibble(.name_repair = "unique") %>%
  {dplyr::mutate(., cluster = kmeans(., 20)$cluster, rn = dplyr::row_number())} %>%
  tidyr::pivot_longer(cols = !c(rn, cluster)) %>%
  dplyr::arrange(cluster) %>%
  dplyr::mutate(rn = as.character(rn) %>% forcats::fct_inorder())

geom_tileで作図

gp <-
  tbl_plot %>%
  ggplot(aes(name, rn)) +
  geom_tile(aes(fill = value)) +
  scale_fill_gradient2() +
  theme_void()
outf <- tempfile(fileext = ".png")
ggsave_ <- purrr::partial(ggsave, width = 300, height = 300, units = "mm", dpi = 600)
ggsave_(outf, gp)
img <- magick::image_read(outf)
geo <- "220x100+620"
(img_crop <- img %>% magick::image_crop(geo) %>% magick::image_trim())

geom_rasterで作図

gp2 <-
  tbl_plot %>%
  ggplot(aes(name, rn)) +
  geom_raster(aes(fill = value)) +
  scale_fill_gradient2() +
  theme_void()
outf2 <- tempfile(fileext = ".png")
ggsave_(outf2, gp2)
img2 <- magick::image_read(outf2)
(img2_crop <- img2 %>% magick::image_crop(geo) %>% magick::image_trim())

比較

左がgeom_tileで作図したもので、右がgeom_rasterで作図したもの。 geom_tileでは出力時に境界部分の描画が曖昧になっているが、 geom_rasterではより正確に描画されている。

Code
magick::image_append(c(
  img_crop %>% magick::image_crop("100x100+80"),
  magick::image_resize(img_crop, "10x100!") %>%
    magick::image_apply(magick::image_fx, expression = "*0+255"),
  img2_crop %>% magick::image_crop("100x100+80")
))

Session info

sessionInfo()
R version 4.3.2 (2023-10-31)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRblas.0.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Asia/Tokyo
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ggplot2_3.5.1  magrittr_2.0.3

loaded via a namespace (and not attached):
 [1] gtable_0.3.5      jsonlite_1.8.8    dplyr_1.1.4       compiler_4.3.2   
 [5] Rcpp_1.0.13       tidyselect_1.2.1  magick_2.8.2      tidyr_1.3.1      
 [9] systemfonts_1.1.0 scales_1.3.0      textshaping_0.4.0 yaml_2.3.9       
[13] fastmap_1.1.1     R6_2.5.1          labeling_0.4.3    generics_0.1.3   
[17] knitr_1.48        htmlwidgets_1.6.4 forcats_1.0.0     tibble_3.2.1     
[21] munsell_0.5.1     pillar_1.9.0      rlang_1.1.4       utf8_1.2.4       
[25] xfun_0.46         cli_3.6.3         withr_3.0.0       digest_0.6.34    
[29] grid_4.3.2        lifecycle_1.0.4   vctrs_0.6.5       evaluate_0.24.0  
[33] glue_1.7.0        farver_2.1.2      ragg_1.3.2        fansi_1.0.6      
[37] colorspace_2.1-1  rmarkdown_2.25    purrr_1.0.2       tools_4.3.2      
[41] pkgconfig_2.0.3   htmltools_0.5.7