web-dev-qa-db-ja.com

ggplot2:geom_ribbonの塗りつぶし色の動作

Ggplot2でリボンを着色しようとしています。 geom_ribbonを使用する場合、yminとymaxおよび塗りつぶしの色を指​​定できます。現在行われているのは、上限または下限に関係なく、yminとymaxの間のすべてに色を付けることです。

例(インターネットから変更):

library("ggplot2")
# Generate data (level2 == level1)
huron <- data.frame(year = 1875:1972, level = as.vector(LakeHuron), level2 = as.vector(LakeHuron))

# Change Level2
huron[1:50,2] <- huron[1:50,2]+100
huron[50:90,2] <- huron[50:90,2]-100

h <- ggplot(huron, aes(year))

h +
  geom_ribbon(aes(ymin = level, ymax = level2), fill = "grey80") +
  geom_line(aes(y = level)) + geom_line(aes(y=level2))

このチャートになります: enter image description here

エリア(ymin> ymax)を、場所(ymin <ymax)とは異なる色で塗りつぶします。実際のデータには、エクスポート値とインポート値があります。そこで、エクスポートがインポートよりも高い領域に色を付け、インポートがエクスポートよりも大きい領域にリボンの色を付けたいと思います。

別の方法:geom_ribbonで領域のみを埋めたい(ymax> ymin)。

誰もこれがどのように行われるか知っていますか?

ご協力いただきありがとうございます。

13
ManuK

別の列を手動で作成する必要がないオプションは、aes(fill =自体内でロジックを実行することです。

## fill dependent on level > level2
h + 
  geom_ribbon(aes(ymin = level, ymax = level2, fill = level > level2)) +
  geom_line(aes(y = level)) + geom_line(aes(y=level2)) +
  scale_fill_manual(values=c("red", "green"), name="fill")

filled conditional on level > level2

または、その条件がtrueであることに基づいてのみ入力する場合、

## fill dependent on level > level2, no fill otherwise
h + 
  geom_ribbon(aes(ymin = level, ymax = level2, fill = ifelse(level > level2, TRUE, NA))) +
  geom_line(aes(y = level)) + geom_line(aes(y=level2)) +
  scale_fill_manual(values=c("green"), name="fill")

filled conditional on level > level2, not otherwise

@beetrootのコードでも同じことが起こるため、補間された塗りつぶしの欠如はggplot2バージョンと関係があるようです。

## @beetroot's answer
huron$id <- 1:nrow(huron)
huron$group <- ifelse(huron$id <= 50, "A", "B") 

h <- ggplot(huron, aes(year))
h +
  geom_ribbon(aes(ymin = level, ymax = level2, fill = group)) +
  geom_line(aes(y = level)) + geom_line(aes(y = level2))    

@beetroot's answer

aes(fill =でロジックなしでそのコードを実行すると、@ ManuKの画像出力が得られます。

14

塗りつぶしの色を指​​定するために使用できるデータにグループ化変数を追加できます。ただし、問題は、ギャップを防ぐために両方のグループに含める必要があるため、2本の線が交差する点です。

最初にこの行を見つけてください。

huron[huron$level == huron$level2,]

> huron[huron$level == huron$level2,]
     year  level level2 
50   1924 577.79 577.79 
...

そして、それをもう一度データに追加します。

huron <- rbind(huron, huron[huron$year == 1924,])
huron <- huron[order(huron$year),]

次に、行インデックスに基づいてid列を追加し、1924年の行番号に基づいてグループを設定します。

huron$id <- 1:nrow(huron)
huron$group <- ifelse(huron$id <= 50, "A", "B") 

h <- ggplot(huron, aes(year))
h +
  geom_ribbon(aes(ymin = level, ymax = level2, fill = group)) +
  geom_line(aes(y = level)) + geom_line(aes(y = level2))

enter image description here

6
beetroot

補間されていないfillで発生した問題を回避するには、2つの(またはn)リボンを使用できます。

h <- ggplot() +
  geom_ribbon(data = huron[huron$level >= huron$level2, ], aes(x = year, ymin = level, ymax = level2), fill="green") +
  geom_ribbon(data = huron[huron$level <= huron$level2, ], aes(x = year, ymin = level, ymax = level2), fill="red") +
  geom_line(data = huron, aes(x = year, y = level)) + 
  geom_line(data = huron, aes(x = year, y = level2))
h

Fill is interpolated now

aes(fill =で使用するすべての条件は、ある要素に強制するため、データが実際に存在する場所にのみ適用されるようです。これはggplot2のバグではないと思います。これは予想される動作だと思います。

4