2017-01-10 4 views
10

マルチパネル/ファセットプロットでは、パネル間にスペースを入れずにパネルをスカッシュすることが可能な場合が好きです。 theme(panel.spacing=grid::unit(0,"lines"))を使用しています(Edward Tufteは、パネル間のスペースが視覚効果を損なうだけでなく、データスペースを浪費するため、これが良いと言います)。ファセットされたggplotsの軸目盛ラベルの衝突を避ける

問題はファセットの行/列内の値の正確な範囲に応じて、隣接するファセットの軸ラベルが重なり合う可能性があります。たとえば、このプロットでは、上部パネルの下部ティックラベルと中央パネルの上部ティックラベルとの間に衝突があります。

dd <- data.frame(x=rep(1:3,3), 
       y=c(0.1,0.2,0.3, 
        0.1,0.4,0.6, 
        1,2,3), 
       f=factor(rep(letters[1:3],each=3))) 
library(ggplot2) 
ggplot(dd,aes(x,y))+ 
    facet_grid(f~.,scale="free")+ 
    geom_point()+ 
    theme_bw(base_size=24)+ 
    theme(panel.spacing=grid::unit(0,"lines")) 
ggsave("tmp1.png",width=4,height=6) 

enter image description here

私は、この問題に対する一般的な、便利なソリューションを構築したい - 範囲があるので、(それは、各ファセットごとに異なります適切な量によって、各ファセットの限界を拡張異質)が、極端な値に対しては(少なくとも)ラベルと(おそらく)目盛りを抑制します。私は過去に特別な目的のbreaksの機能をscale_y_continuousに設定することで、超ハッキーなやり方でこれをやってきました。私はこれを行うための他の方法を考えているかもしれませんが(私はそれらを働かせることができれば回答として投稿します)、私は、(a)labelsを指定するための、 breaks

これは、ファセットで最大/最小値が必要なAutomate tick max and min in faceted ggplotと同じではありません。

これは一般的にやるのは難しいことですが、完全に解決できない可能性があります。私は極端なラベルを空白にすることを考えましたが、2つか3つの目盛ラベルしかなければ失敗します。 expand_limits()の解決策があるかもしれませんが、それはファセット間で行うことは難しいです...

+0

もggplot2のGitHubのレポ上の問題としてこれを提出すべき。 – coatless

+0

おそらく範囲へのブレークをチェックし、極端なラベルの抑制を引き起こす容認できない最小比率を見つけるためにラベルcexと比較するでしょうか?たぶんあなたの以前のハックのより一般的なバージョンを引き起こしても –

+1

私はこれが役に立たないと知っていますが、本当に残念です** ggplot2 **では、まったく新しい(そして一回限りの)原型を学ばなければなりません)OOシステムはちょうどこのような小さな詳細を変更する。 ** lattice **を使うと、カスタム 'prepanel()'と 'yscale.components()'関数を削除し、それを使って処理できます。私は、ここに提出された解決策を楽しみにしています。 –

答えて

3

ビルドデータを変更する可能性があります。元のプロットの限界を取り、乗法的な拡大係数を適用することは可能です。大ブレークとマイナーブレークの相対的な位置も調整が必要です。この関数は、展開が適用されるパネルの選択を可能にすることに注意してください。

expandscale_y_continuousの違いは何ですか?(パネルの選択は別として)この関数は、改行(と目盛りとグリッド線)を元のままにします。それは単に彼らがより少ないスペースを取ることです。ただし、expandは縮尺を圧縮しますが、可能であればggplotは新しいラベル、グリッド線、目盛りを追加します。

最近のバージョンでは、ggplotはビルドデータの要素の名前を変更することが知られていました。

dd <- data.frame(x=rep(1:3,3), 
       y=c(0.1,0.2,0.3, 
        0.1,0.4,0.6, 
        1,2,3), 
       f=factor(rep(letters[1:3],each=3))) 
library(ggplot2) 


p = ggplot(dd,aes(x,y))+ 
    facet_grid(f~.,scale="free")+ 
    geom_point()+ 
    theme_bw(base_size=24)+ 
    theme(panel.spacing=grid::unit(0,"lines")) 


expand = function(plot, mult = 0.1, applyTo) { 
# Get the build data 
gd = ggplot_build(plot) 

# Get the original limits, 
# and calculate the new limits, 
# expanded according to the multiplicative factor 
limits <- sapply(gd$layout$panel_ranges, "[[", "y.range") # Original limits 
fac = mult*(limits[2,] - limits[1, ]) 
newlimits = rbind(limits[1, ] - fac, limits[2, ] + fac) 

# The range for the new limits 
range = newlimits[2, ] - newlimits[1, ] 

# Calculate the new y.major and y.minor relative positions 
# and put them along with the new limits back into the build data 

N = dim(gd$layout$panel_layout)[1] # Number of panels 

for(i in applyTo) { 
y.major = (gd$layout$panel_ranges[[i]]$y.major_source - newlimits[1, i])/range[i] 
y.minor = (gd$layout$panel_ranges[[i]]$y.minor_source - newlimits[1, i])/range[i] 

gd$layout$panel_ranges[[i]]$y.range = newlimits[, i] 

gd$layout$panel_ranges[[i]]$y.major = y.major 
gd$layout$panel_ranges[[i]]$y.minor = y.minor 
} 

# Get the gtable 
ggplot_gtable(gd) 
} 


# Plot it 
grid::grid.draw(expand(p, mult = 0.1, applyTo = 1:2)) 

オリジナル
enter image description here

修正
enter image description here

関連する問題