10

この質問は、この質問をさらに調査することによって動機付けられています。受け入れられたソリューションの問題は、ファセットあたりのバーの数に大きな格差がある場合に、より明白になります。このデータと、その解を使用した結果のプロットを見てください。

# create slightly contrived data to better highlight width problems
data <- data.frame(ID=factor(c(rep(1,9), rep(2,6), rep(3,6), rep(4,3), rep(5,3))),
                   TYPE=factor(rep(1:3,length(ID)/3)),
                   TIME=factor(c(1,1,1,2,2,2,3,3,3,1,1,1,2,2,2,1,1,1,2,2,2,1,1,1,1,1,1)),
                   VAL=runif(27))

# implement previously suggested solution
base.width <- 0.9
data$w <- base.width
# facet two has 3 bars compared to facet one's 5 bars
data$w[data$TIME==2] <- base.width * 3/5
# facet 3 has 1 bar compared to facet one's 5 bars
data$w[data$TIME==3] <- base.width * 1/5
ggplot(data, aes(x=ID, y=VAL, fill=TYPE)) +
  facet_wrap(~TIME, ncol=1, scale="free") +
  geom_bar(position="stack", aes(width = w),stat = "identity") +
  coord_flip()

幅はすべて同じですが、間隔が悪いです

幅は正確に見えますが、ファセット 3 の空白は非常に目立ちます。私がまだ見た ggplot2 でこれを修正する簡単な方法はありません (facet_wrap にはspaceオプションがありません)。

次のステップは、gridExtra を使用してこれを解決することです。

# create each of the three plots, don't worry about legend for now
p1 <- ggplot(data[data$TIME==1,], aes(x=ID, y=VAL, fill=TYPE)) +
  facet_wrap(~ TIME, ncol=1) +
  geom_bar(position="stack", show_guide=FALSE) +
  coord_flip()
p2 <- ggplot(data[data$TIME==2,], aes(x=ID, y=VAL, fill=TYPE)) +
  facet_wrap(~ TIME, ncol=1) +
  geom_bar(position="stack", show_guide=FALSE) +
  coord_flip()
p3 <- ggplot(data[data$TIME==3,], aes(x=ID, y=VAL, fill=TYPE)) +
  facet_wrap(~ TIME, ncol=1) +
  geom_bar(position="stack", show_guide=FALSE) +
  coord_flip()

# use similar arithmetic to try and get layout correct
require(gridExtra)
heights <- c(5, 3, 1) / sum(5, 3, 1)
print(arrangeGrob(p1 ,p2, p3, ncol=1,
            heights=heights))

幅が間違っています

ファセットごとのバーの数に基づいて、以前に提案したのと同じ計算を使用したことに気付くでしょうが、この場合はひどく間違っています. これは、数学で考慮する必要がある追加の「一定の高さ」要素があるためと思われます。

もう 1 つの複雑な点 (と私は信じています) は、最終的な出力 (および幅が一致するかどうか) が、最終的なグロブを出力する場所の幅と高さにも依存することです。 PNG ファイル。

どうすればこれを達成できますか?

4

2 に答える 2

5

このようなものは機能しているように見えますが、機能していません-完全ではありません。IDファクターのレベルがシーケンシャルであるため、機能しているように見えます。それ以外はscale = "free"失敗します。しかし、さらに発展することは可能かもしれません。このメソッドはを使用するfacet_gridため、をspace = "free"使用できます。このメソッドは、geom_rectを使用して、異なる色の長方形を互いに重ねます。各長方形の右端を配置できるように、累積合計を計算する必要があります。

data <- data.frame(ID=factor(c(rep(1,9), rep(2,6), rep(3,6), rep(4,3), rep(5,3))),
                   TYPE=factor(rep(1:3,3)),
                   TIME=factor(c(1,1,1,2,2,2,3,3,3,1,1,1,2,2,2,1,1,1,2,2,2,1,1,1,1,1,1)),
                   VAL=runif(27))

library(ggplot2)
library(plyr)

# Get the cumulative sums
data = ddply(data, .(ID, TIME), mutate, CUMSUMVAL = cumsum(VAL))

ggplot(data, aes(x=VAL, y = as.numeric(ID), fill=TYPE)) +
   geom_rect(data = subset(data, TYPE == 3), aes(xmin = 0, xmax = CUMSUMVAL, ymin = as.numeric(ID)-.2, ymax = as.numeric(ID)+.2)) +
   geom_rect(data = subset(data, TYPE == 2), aes(xmin = 0, xmax = CUMSUMVAL, ymin = as.numeric(ID)-.2, ymax = as.numeric(ID)+.2)) +
   geom_rect(data = subset(data, TYPE == 1), aes(xmin = 0, xmax = CUMSUMVAL, ymin = as.numeric(ID)-.2, ymax = as.numeric(ID)+.2)) +
   facet_grid(TIME~., space = "free", scale="free") +
   scale_y_continuous(breaks = c(1:5), expand = c(0, 0.2))

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

編集: または本当に太い線は少しうまく機能します(私は思う)

ggplot(data, aes(x=VAL, y = ID, colour=TYPE)) +
       geom_segment(data = subset(data, TYPE == 3), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
       geom_segment(data = subset(data, TYPE == 2), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
       geom_segment(data = subset(data, TYPE == 1), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
       facet_grid(TIME~., space = "free", scale="free") 

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

追加の編集 初期の投稿からデータを取得し、少し変更します。
更新 optsは非推奨です。代わりに使用しthemeます。

df <- structure(list(ID = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 
5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L), .Label = c("a", 
"b", "c", "d", "e", "f", "g"), class = "factor"), TYPE = structure(c(1L, 
2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L, 
1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 
5L, 6L, 1L, 2L, 3L), .Label = c("1", "2", "3", "4", "5", "6", 
"7", "8"), class = "factor"), TIME = structure(c(2L, 2L, 2L, 
2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 3L, 3L, 3L, 3L, 3L, 3L, 
1L, 1L, 1L), .Label = c("One", "Five", "Fifteen"), class = "factor"), VAL = c(0.937377670081332, 
0.522220720537007, 0.278690102742985, 0.967633064137772, 0.116124767344445, 
0.0544306698720902, 0.470229141646996, 0.62017166428268, 0.195459847105667, 
0.732876230962574, 0.996336271753535, 0.983087373664603, 0.666449476964772, 
0.291554537601769, 0.167933790013194, 0.860138458199799, 0.172361251665279, 
0.833266809117049, 0.620465772924945, 0.786503327777609, 0.761877260869369, 
0.425386636285111, 0.612077651312575, 0.178726130630821, 0.528709076810628, 
0.492527724476531, 0.472576208412647, 0.0702785139437765, 0.696220921119675, 
0.230852259788662, 0.359884874196723, 0.518227979075164, 0.259466265095398, 
0.149970305617899, 0.00682218233123422, 0.463400925742462, 0.924704828299582, 
0.229068386601284)), .Names = c("ID", "TYPE", "TIME", "VAL"), row.names = c(NA, 
-38L), class = "data.frame")

library(ggplot2)
library(plyr)

data = ddply(df, .(ID, TIME), mutate, CUMSUMVAL = cumsum(VAL))

ggplot(data, aes(x=VAL, y = ID, colour=TYPE)) +
           geom_segment(data = subset(data, TYPE == 6), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
           geom_segment(data = subset(data, TYPE == 5), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
           geom_segment(data = subset(data, TYPE == 4), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
           geom_segment(data = subset(data, TYPE == 3), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
           geom_segment(data = subset(data, TYPE == 2), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
           geom_segment(data = subset(data, TYPE == 1), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
           facet_grid(TIME~., space = "free", scale="free") +
           theme(strip.text.y = element_text(angle = 0))

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

于 2012-07-23T11:46:13.413 に答える
2

残念ながら、バーの幅は相対的な単位であるため、gtableを変更しても効果はありません。

g = ggplot_gtable(ggplot_build(p))
panels = which(sapply(g$heights, attr, "unit") == "null")
g$heights[[panels[1]]] <- unit(5, "null")
g$heights[[panels[2]]] <- unit(3, "null")
g$heights[[panels[3]]] <- unit(1, "null")
grid.draw(g)

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

于 2012-07-23T08:54:20.720 に答える