Ns

長い凡例タイトルのggplot2の凡例タイトルと凡例キーを中央揃えにします



Center Align Legend Title



解決:

2019年10月4日更新:

しばらく前に、ほぼ2年前にここに投稿した元のアイデアに基づいて、かなり一般的な関数を作成しました。この関数はここのgithubにありますが、公式に公開されているパッケージの一部ではありません。これは次のように定義されます。



align_legend<- function(p, hjust = 0.5) { # extract legend g <- cowplot::plot_to_gtable(p) grobs <- g$grobs legend_index <- which(sapply(grobs, function(x) x$name) == 'guide-box') legend <- grobs[[legend_index]] # extract guides table guides_index <- which(sapply(legend$grobs, function(x) x$name) == 'layout') # there can be multiple guides within one legend box for (gi in guides_index) { guides <- legend$grobs[[gi]] # add extra column for spacing # guides$width[5] is the extra spacing from the end of the legend text # to the end of the legend title. If we instead distribute it by `hjust:(1-hjust)` on # both sides, we get an aligned legend spacing <- guides$width[5] guides <- gtable::gtable_add_cols(guides, hjust*spacing, 1) guides$widths[6] <- (1-hjust)*spacing title_index <- guides$layout$name == 'title' guides$layout$l[title_index] <- 2 # reconstruct guides and write back legend$grobs[[gi]] <- guides } # reconstruct legend and write back g$grobs[[legend_index]] <- legend g }  

機能は非常に柔軟で一般的です。使用方法の例を次に示します。

library(ggplot2)library(cowplot)#>#> ************************************** ******************#>注:バージョン1.0.0以降、cowplotは#>デフォルトのggplot2テーマを変更しなくなりました。以前の#>動作を回復するには、次のコマンドを実行します。#> theme_set(theme_cowplot())#> ****************************** **************************ライブラリ(色空間)#単一の凡例p<- ggplot(iris, aes(Sepal.Width, Sepal.Length, color = Petal.Width)) + geom_point() ggdraw(align_legend(p)) # centered  



ggdraw(align_legend(p、hjust = 1))#右揃え

#複数の凡例p2<- ggplot(mtcars, aes(disp, mpg, fill = hp, shape = factor(cyl), size = wt)) + geom_point(color = 'white') + scale_shape_manual(values = c(23, 24, 21), name = 'cylinders') + scale_fill_continuous_sequential(palette = 'Emrld', name = 'power (hp)', breaks = c(100, 200, 300)) + xlab('displacement (cu. in.)') + ylab('fuel efficiency (mpg)') + guides( shape = guide_legend(override.aes = list(size = 4, fill = '#329D84')), size = guide_legend( override.aes = list(shape = 21, fill = '#329D84'), title = 'weight (1000 lbs)') ) + theme_half_open() + background_grid() # works but maybe not the expected result ggdraw(align_legend(p2))  

#より賢明なレイアウトggdraw(align_legend(p2 + theme(legend.position = 'top'、legend.direction = 'vertical')))



reprexパッケージ(v0.3.0)によって2019-10-04に作成されました

元の答え:

私は解決策を見つけました。グロブツリーを掘り下げる必要があり、複数の凡例がある場合は機能しない可能性がありますが、それ以外の場合は、何か良いことが起こるまで、これは合理的な解決策のようです。

library(ggplot2)library(gtable)library(grid)p<- ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width, color=Petal.Width)) + geom_point(size = 3) + scale_color_distiller(palette = 'YlGn', type = 'seq', direction = -1, name = 'Long legend heading
Should be centered') + theme(legend.title.align = 0.5) # extract legend g <- ggplotGrob(p) grobs <- g$grobs legend_index <- which(sapply(grobs, function(x) x$name) == 'guide-box') legend <- grobs[[legend_index]] # extract guides table guides_index <- which(sapply(legend$grobs, function(x) x$name) == 'layout') guides <- legend$grobs[[guides_index]] # add extra column for spacing # guides$width[5] is the extra spacing from the end of the legend text # to the end of the legend title. If we instead distribute it 50:50 on # both sides, we get a centered legend guides <- gtable_add_cols(guides, 0.5*guides$width[5], 1) guides$widths[6] <- guides$widths[2] title_index <- guides$layout$name == 'title' guides$layout$l[title_index] <- 2 # reconstruct legend and write back legend$grobs[[guides_index]] <- guides g$grobs[[legend_index]] <- legend grid.newpage() grid.draw(g)  

ここに画像の説明を入力してください


上記のコメントの1つでbaptisteが説明した方法と同様に、ソースコードをハッキングしました。カラーバー/ラベル/ティックグロブを子gtableに配置し、同じ行スパン/列スパンを持つように配置します(凡例によって異なります)。方向)タイトルとして。

それはまだハックですが、プロットごとに手動で手順を繰り返す必要がなく、「セッション全体で1回ハックする」アプローチと考えたいと思います。

さまざまなタイトル幅/タイトル位置/凡例の方向を使用したデモンストレーション:

plot.demo<- function(title.width = 20, title.position = 'top', legend.direction = 'vertical'){ ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width, color=Petal.Width)) + geom_point(size = 3) + scale_color_distiller(palette = 'YlGn', name = stringr::str_wrap('Long legend heading should be centered', width = title.width), guide = guide_colourbar(title.position = title.position), direction = -1) + theme(legend.title.align = 0.5, legend.direction = legend.direction) } cowplot::plot_grid(plot.demo(), plot.demo(title.position = 'left'), plot.demo(title.position = 'bottom'), plot.demo(title.width = 10, title.position = 'right'), plot.demo(title.width = 50, legend.direction = 'horizontal'), plot.demo(title.width = 10, legend.direction = 'horizontal'), ncol = 2)  

デモ1

これは、複数のカラーバーの凡例でも機能します。

ggplot(iris、aes(x = Sepal.Length、y = Sepal.Width、color = Petal.Width、fill = Petal.Width))+ geom_point(size = 3、shape = 21)+ scale_color_distiller(palette = 'YlGn' 、name = stringr :: str_wrap( '長い凡例の見出しは中央に配置する必要があります'、width = 20)、guide = guide_colourbar(title.position = 'top')、direction = -1)+ scale_fill_distiller(palette = 'RdYlBu'、name = stringr :: str_wrap( '異なる長さの異なる見出し'、幅= 40)、方向= 1)+ theme(legend.title.align = 0.5、legend.direction = 'vertical'、legend.box.just = '中心')

(サイドノート:legend.box.just = 'center'は、2つの凡例を正しく配置するために必要です。現在、「top」、「bottom」、「left」、「right」のみが受け入れ可能なパラメータ値としてリストされているため、しばらく心配していましたが、「center」/「centre」の両方も受け入れられることがわかりました。基礎となるgrid :: valid.just。なぜこれが明示的に言及されていないのかわかりません?テーマヘルプファイル;それにもかかわらず、それは機能します。)

デモ2

ソースコードを変更するには、次のコマンドを実行します。

trace(ggplot2 ::: guide_gengrob.colorbar、edit = TRUE)

そして、コードの最後のセクションをこれから変更します。

gt<- gtable(widths = unit(widths, 'cm'), heights = unit(heights, 'cm')) ... # omitted gt }  

これに:

#凡例gtableを作成し、前と同じように背景/凡例タイトルグロブを追加します(この部分は変更されていません)gt<- gtable(widths = unit(widths, 'cm'), heights = unit(heights, 'cm')) gt <- gtable_add_grob(gt, grob.background, name = 'background', clip = 'off', t = 1, r = -1, b = -1, l = 1) gt <- gtable_add_grob(gt, justify_grobs(grob.title, hjust = title.hjust, vjust = title.vjust, int_angle = title.theme$angle, debug = title.theme$debug), name = 'title', clip = 'off', t = 1 + min(vps$title.row), r = 1 + max(vps$title.col), b = 1 + max(vps$title.row), l = 1 + min(vps$title.col)) # create child gtable, using the same widths / heights as the original legend gtable gt2 <- gtable(widths = unit(widths[1 + seq.int(min(range(vps$bar.col, vps$label.col)), max(range(vps$bar.col, vps$label.col)))], 'cm'), heights = unit(heights[1 + seq.int(min(range(vps$bar.row, vps$label.row)), max(range(vps$bar.row, vps$label.row)))], 'cm')) # shift cell positions to start from 1 vps2 <- vps[c('bar.row', 'bar.col', 'label.row', 'label.col')] vps2[c('bar.row', 'label.row')] <- lapply(vps2[c('bar.row', 'label.row')], function(x) x - min(unlist(vps2[c('bar.row', 'label.row')])) + 1) vps2[c('bar.col', 'label.col')] <- lapply(vps2[c('bar.col', 'label.col')], function(x) x - min(unlist(vps2[c('bar.col', 'label.col')])) + 1) # add bar / ticks / labels grobs to child gtable gt2 <- gtable_add_grob(gt2, grob.bar, name = 'bar', clip = 'off', t = min(vps2$bar.row), r = max(vps2$bar.col), b = max(vps2$bar.row), l = min(vps2$bar.col)) gt2 <- gtable_add_grob(gt2, grob.ticks, name = 'ticks', clip = 'off', t = min(vps2$bar.row), r = max(vps2$bar.col), b = max(vps2$bar.row), l = min(vps2$bar.col)) gt2 <- gtable_add_grob(gt2, grob.label, name = 'label', clip = 'off', t = min(vps2$label.row), r = max(vps2$label.col), b = max(vps2$label.row), l = min(vps2$label.col)) # add child gtable back to original legend gtable, taking tlrb reference from the # rowspan / colspan of the title grob if title grob spans multiple rows / columns. gt <- gtable_add_grob(gt, justify_grobs(gt2, hjust = title.hjust, vjust = title.vjust), name = 'bar.ticks.label', clip = 'off', t = 1 + ifelse(length(vps$title.row) == 1, min(vps$bar.row, vps$label.row), min(vps$title.row)), b = 1 + ifelse(length(vps$title.row) == 1, max(vps$bar.row, vps$label.row), max(vps$title.row)), r = 1 + ifelse(length(vps$title.col) == 1, min(vps$bar.col, vps$label.col), max(vps$title.col)), l = 1 + ifelse(length(vps$title.col) == 1, max(vps$bar.col, vps$label.col), min(vps$title.col))) gt }  

変更を元に戻すには、次のコマンドを実行します。

untrace(ggplot2 ::: guide_gengrob.colorbar)

使用したパッケージバージョン:ggplot23.2.1。


ソースコードを変更する必要があります。現在、タイトルgrobとbar + labelの幅を計算し、ビューポート(gtable)のbar + labelsを左揃えにします。これはハードコーディングされています。