仪表盘图一盘我们常见于测速、或者指示等(如温湿度计、汽车速度表等),实质上和直角坐标图一样,只是把原来的横轴画成了圆形,横轴的值就标度在圆周上,纵轴的值用不同颜色表示阶段或者提示,指针位置表示当前的数值信息。

相对来说我们较少用到,偶然发现在stackoverflow上有人提问并且有大神已经做了代码分享,简单做了调整供读者学习:


# 引用自https://www.r-bloggers.com/2020/10/multiple-gauge-plots-with-facet-wrap/
gauge_plot <- function(vals, breaks=c(0,30,70,100), ncol= NULL) {
    require(ggplot2)
    require(ggthemes)
    require(dplyr)
    require(tidyr)
    
    if (!is.data.frame(vals)) stop("Vals must be a dataframe")
    if (!dim(vals)[2]==2) stop("Vals must have two columns")
    if (!is.numeric(vals$pos)) stop("Dataframe variable pos must be numeric")
    
    
    # 生成多边形函数
    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)))
        df <- data.frame(x,y)
        return(df)
    }
    
    
    # 根据breaks参数创建segments
    segments <- list()
    seg_names <- tibble(x = c("a", "c", "e"), y = c("b", "d" ,"f"))
    
    for(n in 1:3){
        i <-breaks[n]
        j <-breaks[n+1]
        df <- get_poly(i, j)       
        names(df) <- seg_names[n,]
        segments$df[[n]] <- df
    }
    dfs <- bind_cols(segments)
    # 为每个指标创建segments 
    pnt <- tibble()
    for (name in vals$metric){
        pnt[1:nrow(dfs), name] <- name
    }
    
    dfp <- dfs %>% 
        cbind(pnt) %>% 
        pivot_longer(-c(a:f), names_to = "metric") %>% 
        select(-value)
    
    # 创建指针
    needles <- list()
    for(p in 1:nrow(vals)){
        i <-vals$pos[p] - 1
        j <-vals$pos[p] + 1
        r1 <- 0.2
        df <- get_poly(i, j, r1)  
        df$metric <- vals$metric[p]
        needles$df[[p]] <- df
    }
    
    dfn <- bind_rows(needles)
    
    
    # 绘图
    ggplot()+
        geom_polygon(data=dfp, aes(a,b), fill="red")+
        geom_polygon(data=dfp, aes(c,d), fill="gold")+
        geom_polygon(data=dfp, aes(e,f), fill="forestgreen")+
        geom_polygon(data=dfn, aes(x,y))+
        geom_text(data=as.data.frame(breaks), size=3, fontface="bold", vjust=0,
                  aes(x=1.05*cos(pi*(1-breaks/100)),y=1.05*sin(pi*(1-breaks/100)),label=breaks))+
        geom_text(data=vals, aes(x=0,y=0), label=paste0(vals$pos,"%"), vjust=0, size=4, fontface="bold")+
        # 分面
        coord_fixed()+
        theme_few()+
        theme(axis.text=element_blank(),
              axis.title=element_blank(),
              axis.ticks=element_blank(),
              panel.grid=element_blank(),
              panel.border=element_blank()) +
        facet_wrap(~metric, strip.position = "bottom", ncol = ncol) +
        labs(title = "Multiple Gauge Plots \n Facet Wrap")
}

# 示例数据
data <- data.frame(pos=c(89,56,45,54), metric=c("A", "B", "C", "D"))
gauge_plot(data)

参考资料:

1.https://www.r-bloggers.com/2020/10/multiple-gauge-plots-with-facet-wrap/