サークルカットをRで描きたいだけなのに…。
さて、ggimage
パッケージ、用途が良くわかりませんが、ggplot()
でプロットする中に画像を埋め込めるので便利です。
が、なんかアスペクト比がおかしくなるのですよね。たとえば
library(ggimage) ggplot()+geom_image(aes(x=0, y=0), image="circle_title.bmp", size=1, by="width")+coord_equal()
で、こんな感じ。
本当はアスペクト比が勝手に決まるような意図でコードが書かれているようなのですが、有効になっていないようで(原因はちょっと心当たりはある)、内部のコードから必要な部分を取り出して無理やりアスペクト比を変換してみます。
ggimageの内部では下記のようにimage_read2()
という関数で画像を取り込んでいます。
ggimage::image_read2("circle_title.bmp") ## format width height colorspace matte filesize density ## 1 PNG 1008 591 sRGB FALSE 0 72x72
…なのですが、この関数は余白を除いた領域のサイズをとってきます。なんかbmpなのにpngになってますね…。
この関数、画像の表示には良いですが、画像サイズを知りたい場合はこれでは困るので、オリジナルの関数を使います。
magick::image_read("circle_title.bmp") ## format width height colorspace matte filesize density ## 1 BMP3 1152 648 sRGB FALSE 2239542 72x72
こんな感じ。ちなみにこれらの関数は実行するとVIewerペインに画像が表示されます。
また、この戻り値は
str(ggimage::image_read2("circle_title.bmp")) ## Class 'magick-image' <externalptr>
でmagick-imageクラスになっています(どちらの場合も)。このクラスのオブジェクトが持っている画像の情報を抜き出すにはmagick::image_info()
を使います。
magick::image_info(magick::image_read("circle_title.bmp")) ## format width height colorspace matte filesize density ## 1 BMP3 1152 648 sRGB FALSE 2239542 72x72
これで、widthとheightを知ることが出来ました。この値をとってくるにはそれぞれ
image_width <- magick::image_info(magick::image_read("circle_title.bmp"))$width image_width ## [1] 1152 image_height <- magick::image_info(magick::image_read("circle_title.bmp"))$height image_height ## [1] 648
でよいです。あとはgeom_image()
の引数aspに↑で得た幅と高さからアスペクト比を計算して与え、表示領域の固定をします。
ggplot()+geom_image(aes(x=0, y=0), image="circle_title.png", size=1, by="width", asp=image_width/image_height)+ coord_fixed()+xlim(-image_width/2, image_width/2)+ylim(-image_height/2, image_height/2)
これに軸を消したり背景消したり…ということをthemeで与えてあげると…
ggplot()+geom_image(aes(x=0, y=0), image="circle_title.png", size=1, by="width", asp=image_width/image_height)+ coord_fixed()+xlim(-image_width/2, image_width/2)+ylim(-image_height/2, image_height/2)+ theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line = element_line(colour = "black", size=1), axis.text = element_blank(), axis.title = element_blank(), axis.ticks.length = grid::unit(rep(0, 4), "points"), axis.ticks = element_blank(), axis.line.x = element_blank(), axis.line.y = element_blank(), plot.margin=grid::unit(rep(0, 4), "points"))
と、オリジナルの画像そのままの表示となりました。
あとはこれに好きな文字を足したり、plotを重ねたりしてあげればよいですね。
ようやくこれでサークルカットが描ける…よかったよかった。
Enjoy!!