14

Rで次のプロットを描くにはどうすればよいですか?

  Red = 30
  Yellow = 40
  Green = 30 

  Needle at 52. 

私は非常に困っているので、助けてください。

ありがとう

ここに画像の説明を入力

4

4 に答える 4

36

だからここに完全なggplot解決策があります。

注:元の投稿から編集して、ゲージブレークに数値インジケーターとラベルを追加しました。これは、OPがコメントで求めているようです。インジケーターが不要な場合は、annotate(...)行を削除します。ラベルが不要な場合は、geom_text(...)行を削除してください。

gg.gauge <- function(pos,breaks=c(0,30,70,100)) {
  require(ggplot2)
  get.poly <- function(a,b,r1=0.5,r2=1.0) {
    th.start <- pi*(1-a/100)
    th.end   <- pi*(1-b/100)
    th       <- seq(th.start,th.end,length=100)
    x        <- c(r1*cos(th),rev(r2*cos(th)))
    y        <- c(r1*sin(th),rev(r2*sin(th)))
    return(data.frame(x,y))
  }
  ggplot()+ 
    geom_polygon(data=get.poly(breaks[1],breaks[2]),aes(x,y),fill="red")+
    geom_polygon(data=get.poly(breaks[2],breaks[3]),aes(x,y),fill="gold")+
    geom_polygon(data=get.poly(breaks[3],breaks[4]),aes(x,y),fill="forestgreen")+
    geom_polygon(data=get.poly(pos-1,pos+1,0.2),aes(x,y))+
    geom_text(data=as.data.frame(breaks), size=5, fontface="bold", vjust=0,
              aes(x=1.1*cos(pi*(1-breaks/100)),y=1.1*sin(pi*(1-breaks/100)),label=paste0(breaks,"%")))+
    annotate("text",x=0,y=0,label=pos,vjust=0,size=8,fontface="bold")+
    coord_fixed()+
    theme_bw()+
    theme(axis.text=element_blank(),
          axis.title=element_blank(),
          axis.ticks=element_blank(),
          panel.grid=element_blank(),
          panel.border=element_blank()) 
}
gg.gauge(52,breaks=c(0,35,70,100))

## multiple guages
library(gridExtra)
grid.newpage()
grid.draw(arrangeGrob(gg.gauge(10),gg.gauge(20),
                      gg.gauge(52),gg.gauge(90),ncol=2))

ゲージの実際のサイズに応じて、size=...パラメーターを微調整する必要がある可能性があります。geom_text(...)annotate(...)

IMO セグメント ラベルは非常に悪い考えです。画像を乱雑にし、グラフィックの目的を無効にします (メトリックが「安全」、「警告」、または「危険」領域にあるかどうかを一目で示すため)。

于 2014-07-23T21:55:46.870 に答える
11

これは、グリッドグラフィックを使用した非常に迅速で汚い実装です

library(grid)

draw.gauge<-function(x, from=0, to=100, breaks=3, 
    label=NULL, axis=TRUE, cols=c("red","yellow","green")) {

    if (length(breaks)==1) {
        breaks <- seq(0, 1, length.out=breaks+1)
    } else {
        breaks <- (breaks-from)/(to-from)
    }
    stopifnot(length(breaks) == (length(cols)+1))

    arch<-function(theta.start, theta.end, r1=1, r2=.5, col="grey", n=100) {
        t<-seq(theta.start, theta.end, length.out=n)
        t<-(1-t)*pi
        x<-c(r1*cos(t), r2*cos(rev(t)))
        y<-c(r1*sin(t), r2*sin(rev(t)))
        grid.polygon(x,y, default.units="native", gp=gpar(fill=col))
    }
    tick<-function(theta, r, w=.01) {
        t<-(1-theta)*pi
        x<-c(r*cos(t-w), r*cos(t+w), 0) 
        y<-c(r*sin(t-w), r*sin(t+w), 0) 
        grid.polygon(x,y, default.units="native", gp=gpar(fill="grey"))
    }
    addlabel<-function(m, theta, r) {
        t<-(1-theta)*pi      
        x<-r*cos(t)
        y<-r*sin(t) 
        grid.text(m,x,y, default.units="native")
    }

    pushViewport(viewport(w=.8, h=.40, xscale=c(-1,1), yscale=c(0,1)))
    bp <- split(t(embed(breaks, 2)), 1:2)
    do.call(Map, list(arch, theta.start=bp[[1]],theta.end=bp[[2]], col=cols))
    p<-(x-from)/(to-from)
    if (!is.null(axis)) {
            if(is.logical(axis) && axis) {
            m <- round(breaks*(to-from)+from,0)
            } else if (is.function(axis)) {
            m <- axis(breaks, from, to)
            } else if(is.character(axis)) {
            m <- axis
            } else {
                   m <- character(0)
            }
        if(length(m)>0) addlabel(m, breaks, 1.10)
    }
    tick(p, 1.03)
    if(!is.null(label)) {
            if(is.logical(label) && label) {
            m <- x
            } else if (is.function(label)) {
            m <- label(x)
            } else {
            m <- label
            }
            addlabel(m, p, 1.15)
    }
    upViewport()
}

この関数は、1 つのゲージを描画するために使用できます。

grid.newpage()
draw.gauge(100*runif(1))

または多くのゲージ

grid.newpage()
pushViewport(viewport(layout=grid.layout(2,2)))
for(i in 1:4) {
    pushViewport(viewport(layout.pos.col=(i-1) %/%2 +1, layout.pos.row=(i-1) %% 2 + 1))
    draw.gauge(100*runif(1))
    upViewport()
}
popViewport()

派手すぎないので、カスタマイズしやすいはずです。

ここに画像の説明を入力

ラベルも追加できるようになりました

draw.gauge(75, label="75%")

ここに画像の説明を入力

「軸」を描画できるように別の更新を追加しました。TRUE に設定してデフォルト値を使用するか、文字ベクトルを渡して任意のラベルを付けるか、ブレーク (スケーリングされた 0-1) と from/to 値を取る関数を渡すことができます。文字値を返す必要があります。

grid.newpage()
draw.gauge(100*runif(1), breaks=c(0,30,70,100), axis=T)

ここに画像の説明を入力

于 2014-07-23T03:44:28.913 に答える