web-dev-qa-db-ja.com

ggplot2のエラーバーの幅

標準エラーが関連付けられたデータがいくつかあり、これらをエラーバーで表示したいと思います。それは私が持っているものです:

_# generate some data
hod <- data.frame(h = c(1:24,1:24,1:24), mean = 1:(24*3) + runif(24*3, 0, 5),ci = runif(24*3, 0, 2), t = c(rep("a",24),rep("b",24),rep("c",24)))

pd <- position_dodge(0.3)
  dayplot <- ggplot(hod, aes(x=h, y=mean, colour=as.factor(t),group=as.factor(t))) + 
    geom_line(position=pd, size=1) +
    geom_errorbar(aes(ymin=mean-ci, ymax=mean+ci),
                  width=1,
                  size=0.5,
                  position=pd) +
    geom_point(position=pd, shape=21, size=1, fill="white") +
    scale_x_continuous(limits=c(-0.5,23.5),
                       breaks=c(0:8*3),
                       labels=ifelse(
                              c(0:8*3) < 10,
                              paste('0',c(0:8*3),':00',sep=''),
                              paste(c(0:8*3),':00',sep='')
                              )
                       ) +
    xlab("Hour of day") + ylab(ylabel) + labs(title = varlabels[var]) +
    theme_minimal() + 
    theme(plot.margin = unit(c(1,0,1,1), "cm"), 
          axis.title.x = element_text(vjust=-1),
          axis.title.y = element_text(angle=90, vjust=0),
          legend.margin = unit(c(0), "cm"),
          legend.key.height = unit(c(0.9), "cm"),
          panel.grid.major = element_line(colour=rgb(0.87,0.87,0.87)),
          panel.grid.minor = element_blank(),
          plot.background = element_rect(fill = rgb(0.97,0.97,0.97), linetype=0)
    )
_

おそらく興味深いのは次のとおりです。

_geom_errorbar(aes(ymin=mean-ci, ymax=mean+ci),
                      width=1,
                      size=0.5,
                      position=pd)
_

それは与えます: all

データを因子変数(as.factor(t))でグループ化すると、1行ではなく複数行が表示されます。これは私が望むものですが、ご覧のとおり、エラーバーの水平線はもっと多くなっています。狭くて、理由がわかりません。 _geom_errorbar_のwidth属性とsize属性を変更し、削除しようとしましたが、何も起こりません。データに関係なく、すべてのグラフで水平線の幅を同じにする方法はありますか?つまり、なぜそれが変化する必要があるのですか?それとも、その幅はいくつかの情報を伝えますか?

enter image description here

13
wnstnsmth

以下は、ランダムデータを使用した再現可能な例です。この問題の修正は、幅にクラス/ファクターの数を掛けることです。以下のプロットでは、3つの要素を使用したため、幅3を使用すると問題が解決します。 ggplot2は、x軸の数値ではなく、データセット内のデータポイントの数によって相対幅を計算しているようです。これは(IMO)バグです。

library(ggplot2)
library(grid)

#plot with factors
hod <- data.frame(h = c(1:24,1:24,1:24), mean = 1:(24*3) + runif(24*3, 0, 5),ci = runif(24*3, 0, 2), t = c(rep("a",24),rep("b",24),rep("c",24)))
pd <- position_dodge(0.3)
  dayplot <- ggplot(hod, aes(x=h, y=mean, colour=as.factor(t),group=as.factor(t))) + 

    geom_line(position=pd, size=1) +
    geom_errorbar(aes(ymin=mean-ci, ymax=mean+ci),
                  width=1,
                  size=0.5,
                  position=pd) +
    geom_point(position=pd, shape=21, size=1, fill="white") +
    scale_x_continuous(limits=c(-0.5,23.5),
                       breaks=c(0:8*3),
                       labels=ifelse(
                              c(0:8*3) < 10,
                              paste('0',c(0:8*3),':00',sep=''),
                              paste(c(0:8*3),':00',sep='')
                              )
                       ) +
    xlab("Hour of day") +
    theme_minimal() + 
    theme(plot.margin = unit(c(1,0,1,1), "cm"), 
          axis.title.x = element_text(vjust=-1),
          axis.title.y = element_text(angle=90, vjust=0),
          legend.margin = unit(c(0), "cm"),
          legend.key.height = unit(c(0.9), "cm"),
          panel.grid.major = element_line(colour=rgb(0.87,0.87,0.87)),
          panel.grid.minor = element_blank(),
          plot.background = element_rect(fill = rgb(0.97,0.97,0.97), linetype=0)
    )
print(dayplot)


#plot without factors
hod <- data.frame(h = c(1:24,1:24,1:24), mean = 1:(24) + runif(24, 0, 5),ci = runif(24, 0, 2))
pd <- position_dodge(0.3)
  dayplot <- ggplot(hod, aes(x=h, y=mean)) + 

    geom_line(position=pd, size=1) +
    geom_errorbar(aes(ymin=mean-ci, ymax=mean+ci),
                  width=1,
                  size=0.5,
                  position=pd) +
    geom_point(position=pd, shape=21, size=1, fill="white") +
    scale_x_continuous(limits=c(-0.5,23.5),
                       breaks=c(0:8*3),
                       labels=ifelse(
                              c(0:8*3) < 10,
                              paste('0',c(0:8*3),':00',sep=''),
                              paste(c(0:8*3),':00',sep='')
                              )
                       ) +
    xlab("Hour of day") +
    theme_minimal() + 
    theme(plot.margin = unit(c(1,0,1,1), "cm"), 
          axis.title.x = element_text(vjust=-1),
          axis.title.y = element_text(angle=90, vjust=0),
          legend.margin = unit(c(0), "cm"),
          legend.key.height = unit(c(0.9), "cm"),
          panel.grid.major = element_line(colour=rgb(0.87,0.87,0.87)),
          panel.grid.minor = element_blank(),
          plot.background = element_rect(fill = rgb(0.97,0.97,0.97), linetype=0)
    )

print(dayplot)
8
thc

私はなんとか同様の問題を解決することができました。私の場合、プロットのアスペクト比に関係なく、水平方向と垂直方向の両方のエラーバーヘッドを同じサイズに設定したいと思いました。

元の投稿コードに基づく:

f <- ggplot_build(dayplot)

f$plot$layers[[5]]$geom_params$width  <- 0.02 * diff(f$layout$panel_params[[1]]$x.range)
f$plot$layers[[6]]$geom_params$height <- 0.02 * diff(f$layout$panel_params[[1]]$y.range)

dayplot <- f$plot

これにより、エラーバーのヘッドが軸範囲の2%に設定されます。多分あなたの問題を解決することができます。

0
ThiagoMAF