2つの異なるy軸でプロットするにはどうすればよいですか?


122

Rで2つの散布図を重ね合わせて、ポイントの各セットが独自の(異なる)y軸を持つようにします(つまり、図の位置2と4に)が、ポイントは同じ図に重ねて表示されます。

これを使ってこれを行うことは可能plotですか?

問題を示すサンプルコードを編集する

# example code for SO question
y1 <- rnorm(10, 100, 20)
y2 <- rnorm(10, 1, 1)
x <- 1:10
# in this plot y2 is plotted on what is clearly an inappropriate scale
plot(y1 ~ x, ylim = c(-1, 150))
points(y2 ~ x, pch = 2)

サンプルデータを提供してください。これは一般に、美的観点からすると悪い考えです。
追跡

3
特定の場合の回答とディスカッションggplot2stackoverflow.com/questions/3099219/…(SOを検索する[r] two y-axesまたは[r] twoord.plot)-他にいくつかの関連する回答がありますが、(R FAQ
なので驚いたことに

@chase-問題の実際の例を追加しました。美的問題に関する警告をありがとう。
DQdlM、2011年

回答:


126

更新http ://rwiki.sciviews.org/doku.php?id=tips:graphics-base:2yaxesのR wikiにあったコピーされた資料、リンクが壊れた:ウェイバックマシンからも利用可能

同じプロット上の2つの異なるy軸

(Daniel Rajdl 2006/03/31 15:26によるいくつかの資料)

同じプロットで2つの異なるスケールを使用することが適切である状況はほとんどないことに注意してください。グラフィックの閲覧者を誤解させることは非常に簡単です。以下の2つの例とコメント、この問題に関する(確認例1例2からジャンクチャート)、などによって、この記事をステファン・フューデュアルスケール軸を持つグラフは決してしないことを、私は確かに、結論一度、すべてのことができない」と結論(便利です。他のより良い解決策に照らして彼らを正当化できる状況を考えることができないということだけです。」)また、この漫画のポイント4を参照してください...

決定した場合、基本的なレシピは、最初のプロットを作成par(new=TRUE)し、Rがグラフィックスデバイスをクリアしないように設定し、2番目のプロットを作成してaxes=FALSE(および設定xlabylabて空白にすることann=FALSEもできます)、次にを使用axis(side=4)して新しい軸を追加することです右側にありmtext(...,side=4)、軸ラベルを右側に追加します。以下は、作成されたデータを少し使用した例です。

set.seed(101)
x <- 1:10
y <- rnorm(10)
## second data set on a very different scale
z <- runif(10, min=1000, max=10000) 
par(mar = c(5, 4, 4, 4) + 0.3)  # Leave space for z axis
plot(x, y) # first plot
par(new = TRUE)
plot(x, z, type = "l", axes = FALSE, bty = "n", xlab = "", ylab = "")
axis(side=4, at = pretty(range(z)))
mtext("z", side=4, line=3)

twoord.plot()plotrixパッケージでは、パッケージと同様doubleYScale()に、このプロセスを自動化しlatticeExtraます。

別の例(Robert W. BaerによるRメーリングリストの投稿から抜粋):

## set up some fake test data
time <- seq(0,72,12)
betagal.abs <- c(0.05,0.18,0.25,0.31,0.32,0.34,0.35)
cell.density <- c(0,1000,2000,3000,4000,5000,6000)

## add extra space to right margin of plot within frame
par(mar=c(5, 4, 4, 6) + 0.1)

## Plot first set of data and draw its axis
plot(time, betagal.abs, pch=16, axes=FALSE, ylim=c(0,1), xlab="", ylab="", 
   type="b",col="black", main="Mike's test data")
axis(2, ylim=c(0,1),col="black",las=1)  ## las=1 makes horizontal labels
mtext("Beta Gal Absorbance",side=2,line=2.5)
box()

## Allow a second plot on the same graph
par(new=TRUE)

## Plot the second plot and put axis scale on right
plot(time, cell.density, pch=15,  xlab="", ylab="", ylim=c(0,7000), 
    axes=FALSE, type="b", col="red")
## a little farther out (line=4) to make room for labels
mtext("Cell Density",side=4,col="red",line=4) 
axis(4, ylim=c(0,7000), col="red",col.axis="red",las=1)

## Draw the time axis
axis(1,pretty(range(time),10))
mtext("Time (Hours)",side=1,col="black",line=2.5)  

## Add Legend
legend("topleft",legend=c("Beta Gal","Cell Density"),
  text.col=c("black","red"),pch=c(16,15),col=c("black","red"))

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

同様のレシピを使用して、さまざまなタイプのプロット(棒グラフ、ヒストグラムなど)を重ね合わせることができます。


これが、リンクのみの回答が悪い考えである理由です... wiki.r-project.orgは機能していないようです。r-devel@ r-project.orgに質問しています。
ベンボルカー2014

@BenBolkerあなたの解決策は天才です!しかし、私は1つの質問があります。両側に複数の線がある場合でも、この方法は使用できますが、記号のみが必要です。line = plotを使用しようとすると、継続的にプロットされます。これを修正するためのトリックを提案しますか?
wthimdh 2017年

1
@BenBolker時刻が「2019-01-01」タイプの日付形式の場合はどうなりますか。どのようにaxis(1,pretty(range(time),10))ラインを変更しますか?
k.dkhk

35

その名前が示すようtwoord.plot()に、plotrixパッケージでは、2つの縦軸を使用してプロットします。

library(plotrix)
example(twoord.plot)

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

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

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

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

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


3
スリック。例のトラック負荷をありがとう。また、負の値を持つこれらの線と棒の例の1つを参照してください。スタッキングもいいですね。
Matt Bannert 16

5

1つのオプションは、2つのプロットを並べて作成することです。ggplot2これのための素晴らしいオプションを提供しますfacet_wrap()

dat <- data.frame(x = c(rnorm(100), rnorm(100, 10, 2))
  , y = c(rnorm(100), rlnorm(100, 9, 2))
  , index = rep(1:2, each = 100)
  )

require(ggplot2)
ggplot(dat, aes(x,y)) + 
geom_point() + 
facet_wrap(~ index, scales = "free_y")

4

スケール/軸ラベルを放棄できる場合は、データを(0、1)間隔に再スケールできます。これは、たとえば、トラック間の局所的な相関関係に興味があり、それらが異なるスケール(1000でのカバレッジ、Fst 0-1)を持っている場合に、染色体上のさまざまな「ウィグル」トラックで機能します。

# rescale numeric vector into (0, 1) interval
# clip everything outside the range 
rescale <- function(vec, lims=range(vec), clip=c(0, 1)) {
  # find the coeficients of transforming linear equation
  # that maps the lims range to (0, 1)
  slope <- (1 - 0) / (lims[2] - lims[1])
  intercept <- - slope * lims[1]

  xformed <- slope * vec + intercept

  # do the clipping
  xformed[xformed < 0] <- clip[1]
  xformed[xformed > 1] <- clip[2]

  xformed
}

そして、データのフレーム持つchrompositioncoverageおよびfst列を、あなたのような何かを行うことができます:

ggplot(d, aes(position)) + 
  geom_line(aes(y = rescale(fst))) + 
  geom_line(aes(y = rescale(coverage))) +
  facet_wrap(~chrom)

これの利点は、2つのトラックに制限されないことです。


4

私も提案twoord.stackplot()plotrixますが、パッケージでは縦軸が2つ以上あるプロットです。

data<-read.table(text=
"e0AL fxAL e0CO fxCO e0BR fxBR anos
 51.8  5.9 50.6  6.8 51.0  6.2 1955
 54.7  5.9 55.2  6.8 53.5  6.2 1960
 57.1  6.0 57.9  6.8 55.9  6.2 1965
 59.1  5.6 60.1  6.2 57.9  5.4 1970
 61.2  5.1 61.8  5.0 59.8  4.7 1975
 63.4  4.5 64.0  4.3 61.8  4.3 1980
 65.4  3.9 66.9  3.7 63.5  3.8 1985
 67.3  3.4 68.0  3.2 65.5  3.1 1990
 69.1  3.0 68.7  3.0 67.5  2.6 1995
 70.9  2.8 70.3  2.8 69.5  2.5 2000
 72.4  2.5 71.7  2.6 71.1  2.3 2005
 73.3  2.3 72.9  2.5 72.1  1.9 2010
 74.3  2.2 73.8  2.4 73.2  1.8 2015
 75.2  2.0 74.6  2.3 74.2  1.7 2020
 76.0  2.0 75.4  2.2 75.2  1.6 2025
 76.8  1.9 76.2  2.1 76.1  1.6 2030
 77.6  1.9 76.9  2.1 77.1  1.6 2035
 78.4  1.9 77.6  2.0 77.9  1.7 2040
 79.1  1.8 78.3  1.9 78.7  1.7 2045
 79.8  1.8 79.0  1.9 79.5  1.7 2050
 80.5  1.8 79.7  1.9 80.3  1.7 2055
 81.1  1.8 80.3  1.8 80.9  1.8 2060
 81.7  1.8 80.9  1.8 81.6  1.8 2065
 82.3  1.8 81.4  1.8 82.2  1.8 2070
 82.8  1.8 82.0  1.7 82.8  1.8 2075
 83.3  1.8 82.5  1.7 83.4  1.9 2080
 83.8  1.8 83.0  1.7 83.9  1.9 2085
 84.3  1.9 83.5  1.8 84.4  1.9 2090
 84.7  1.9 83.9  1.8 84.9  1.9 2095
 85.1  1.9 84.3  1.8 85.4  1.9 2100", header=T)

require(plotrix)
twoord.stackplot(lx=data$anos, rx=data$anos, 
                 ldata=cbind(data$e0AL, data$e0BR, data$e0CO),
                 rdata=cbind(data$fxAL, data$fxBR, data$fxCO),
                 lcol=c("black","red", "blue"),
                 rcol=c("black","red", "blue"), 
                 ltype=c("l","o","b"),
                 rtype=c("l","o","b"), 
                 lylab="Años de Vida", rylab="Hijos x Mujer", 
                 xlab="Tiempo",
                 main="Mortalidad/Fecundidad:1950–2100",
                 border="grey80")
legend("bottomright", c(paste("Proy:", 
                      c("A. Latina", "Brasil", "Colombia"))), cex=1,
        col=c("black","red", "blue"), lwd=2, bty="n",  
        lty=c(1,1,2), pch=c(NA,1,1) )

1

@BenBolkerによって受け入れられた回答に類似した別の代替方法は、2番目のポイントセットを追加するときに既存のプロットの座標を再定義することです。

これは最小限の例です。

データ:

x  <- 1:10
y1 <- rnorm(10, 100, 20)
y2 <- rnorm(10, 1, 1)

プロット:

par(mar=c(5,5,5,5)+0.1, las=1)

plot.new()
plot.window(xlim=range(x), ylim=range(y1))
points(x, y1, col="red", pch=19)
axis(1)
axis(2, col.axis="red")
box()

plot.window(xlim=range(x), ylim=range(y2))
points(x, y2, col="limegreen", pch=19)
axis(4, col.axis="limegreen")

例

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.