关闭 ggplot2 雷达/蜘蛛图中的线条

Closing the lines in a ggplot2 radar / spider chart

我需要一种灵活的方法来在 ggplot2 中制作雷达图/蜘蛛图。从我在 github 和 ggplot2 组上找到的解决方案,我已经走到这一步了:

library(ggplot2) 

# Define a new coordinate system 
coord_radar <- function(...) { 
  structure(coord_polar(...), class = c("radar", "polar", "coord")) 
} 
is.linear.radar <- function(coord) TRUE 

# rescale all variables to lie between 0 and 1 
scaled <- as.data.frame(lapply(mtcars, ggplot2:::rescale01))

scaled$model <- rownames(mtcars)    # add model names as a variable 

as.data.frame(melt(scaled,id.vars="model")) -> mtcarsm

ggplot(mtcarsm, aes(x = variable, y = value)) + 
    geom_path(aes(group = model)) +
    coord_radar() + facet_wrap(~ model,ncol=4) + 
    theme(strip.text.x = element_text(size = rel(0.8)), 
          axis.text.x = element_text(size = rel(0.8)))

这有效,除了线路没有关闭这一事实。 我认为我可以做到这一点:

mtcarsm <- rbind(mtcarsm,subset(mtcarsm,variable == names(scaled)[1]))
ggplot(mtcarsm, aes(x = variable, y = value)) + 
    geom_path(aes(group = model)) +
    coord_radar() + facet_wrap(~ model,ncol=4) + 
    theme(strip.text.x = element_text(size = rel(0.8)), 
          axis.text.x = element_text(size = rel(0.8)))

为了加入线路,但是这个不行。这也不是:

closes <- subset(mtcarsm,variable == names(scaled)[c(1,11)])
ggplot(mtcarsm, aes(x = variable, y = value)) + 
    geom_path(aes(group = model)) +
    coord_radar() + facet_wrap(~ model,ncol=4) + 
    theme(strip.text.x = element_text(size = rel(0.8)), 
          axis.text.x = element_text(size = rel(0.8))) + geom_path(data=closes)

这并没有解决问题,而且还产生了很多

"geom_path: Each group consist of only one observation. Do you need to adjust the group aesthetic?"

条消息。 Som,我该如何关闭线路?

/弗雷德里克

对不起,我是愚蠢的。这似乎有效:

library(ggplot2) 

# Define a new coordinate system 
coord_radar <- function(...) { 
  structure(coord_polar(...), class = c("radar", "polar", "coord")) 
} 
is.linear.radar <- function(coord) TRUE 

# rescale all variables to lie between 0 and 1 
scaled <- as.data.frame(lapply(mtcars, ggplot2:::rescale01))

scaled$model <- rownames(mtcars)    # add model names as a variable 

as.data.frame(melt(scaled,id.vars="model")) -> mtcarsm


mtcarsm <- rbind(mtcarsm,subset(mtcarsm,variable == names(scaled)[1]))
ggplot(mtcarsm, aes(x = variable, y = value)) + 
    geom_path(aes(group = model)) +
    coord_radar() + facet_wrap(~ model,ncol=4) + 
    theme(strip.text.x = element_text(size = rel(0.8)), 
          axis.text.x = element_text(size = rel(0.8))) 

事实证明 geom_polygom 仍然会在极坐标中生成一个多边形,因此

# rescale all variables to lie between 0 and 1
scaled <- as.data.frame(lapply(mtcars, ggplot2:::rescale01))
scaled$model <- rownames(mtcars)    # add model names as a variable
# melt the dataframe
mtcarsm <- reshape2::melt(scaled)
# plot it as using the polygon geometry in the polar coordinates
ggplot(mtcarsm, aes(x = variable, y = value)) +
geom_polygon(aes(group = model), color = "black", fill = NA, size = 1) +
coord_polar() + facet_wrap( ~ model) +
theme(strip.text.x = element_text(size = rel(0.8)),
    axis.text.x = element_text(size = rel(0.8)),
    axis.ticks.y = element_blank(),
    axis.text.y = element_blank()) +
xlab("") + ylab("")

完美运行...

使用 ggplot2 2.0.0 中可用的新 ggproto 机制,coord_radar 可以定义为:

coord_radar <- function (theta = "x", start = 0, direction = 1) 
{
 theta <- match.arg(theta, c("x", "y"))
 r <- if (theta == "x") 
        "y"
      else "x"
 ggproto("CoordRadar", CoordPolar, theta = theta, r = r, start = start, 
      direction = sign(direction),
      is_linear = function(coord) TRUE)
}

不确定语法是否完美,但它正在工作...

此处的代码对于 ggplot2: 2.0.0

似乎已过时

试试我的包 zmisc:devtools:install_github("jerryzhujian9/ezmisc")

安装后,您将可以运行:

df = mtcars
df$model = rownames(mtcars)

ez.radarmap(df, "model", stats="mean", lwd=1, angle=0, fontsize=0.6, facet=T, facetfontsize=1, color=id, linetype=NULL)
ez.radarmap(df, "model", stats="none", lwd=1, angle=0, fontsize=1.5, facet=F, facetfontsize=1, color=id, linetype=NULL)

如果你对里面的内容感到好奇,请查看我的代码 github:

主要代码改编自http://www.cmap.polytechnique.fr/~lepennec/R/Radar/RadarAndParallelPlots.html

谢谢你们的帮助,但它并没有满足我的所有需求。我使用了两个系列的数据进行比较,所以我为马自达取了 mtcars 的子集:

  1. 没有人提到 x 变量的顺序,ggplot2 对该变量进行排序以用于绘图但不对数据进行排序,这让我的图表在第一次尝试时就出错了。为我应用排序功能是 dplyr::arrange(plot.data, x.variable.name)

  2. 我需要用值注释图表,ggplot2::annotate() 工作正常,但它没有包含在最近的答案中

  3. 在添加 ggplot2::geom_line

  4. 之前,上述代码对我的数据无法正常工作

最后这个代码块完成了我的图表:

scaled <- as.data.frame(lapply(mtcars, ggplot2:::rescale01))
scaled$model <- rownames(mtcars)
mtcarsm <- scaled %>%
  filter(grepl('Mazda', model)) %>% 
  gather(variable, value, mpg:carb) %>% 
  arrange(variable)


ggplot(mtcarsm, aes(x = variable, y = value)) + 
  geom_polygon(aes(group = model, color = model), fill = NA, size = 1) +
  geom_line(aes(group = model, color = model), size = 1) + 
  annotate("text", x = mtcarsm$variable, y = (mtcarsm$value + 0.05), label = round(mtcarsm$value, 2), size = 3) +
  theme(strip.text.x = element_text(size = rel(0.8)),
        axis.text.x = element_text(size = rel(1.2)),
        axis.ticks.y = element_blank(),
        axis.text.y = element_blank()) +
  xlab("") + ylab("") +
  guides(color = guide_legend()) +
  coord_radar()

希望对某人有用

  • 解决关键因素
    1. melt 之后添加重复的 mpgrbind
    2. ggproto
    3. 上继承 CoordPolar
    4. ggproto
    5. 上设置 is_linear = function() TRUE

尤其是is_linear = function() TRUE很重要,
因为如果不是你会得到这样的情节......

通过is_linear = function() TRUE设置你可以获得,

library(dplyr)
library(data.table)
library(ggplot2)

rm(list=ls())

scale_zero_to_one <- 
  function(x) {
    r <- range(x, na.rm = TRUE)
    min <- r[1]
    max <- r[2]
    (x - min) / (max - min)
  }

scaled.data <-
  mtcars %>%
  lapply(scale_zero_to_one) %>%
  as.data.frame %>%
  mutate(car.name=rownames(mtcars)) 

plot.data <-
  scaled.data %>%
  melt(id.vars='car.name') %>%
  rbind(subset(., variable == names(scaled.data)[1]))

# create new coord : inherit coord_polar
coord_radar <- 
  function(theta='x', start=0, direction=1){
    # input parameter sanity check
    match.arg(theta, c('x','y'))

    ggproto(
      NULL, CoordPolar, 
      theta=theta, r=ifelse(theta=='x','y','x'),
      start=start, direction=sign(direction),
      is_linear=function() TRUE)
  }

plot.data %>%
  ggplot(aes(x=variable, y=value, group=car.name, colour=car.name)) + 
  geom_path() +
  geom_point(size=rel(0.9)) +
  coord_radar() + 
  facet_wrap(~ car.name, nrow=4) + 
  theme_bw() +
  theme(
    axis.title.y = element_blank(),
    axis.text.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_blank(),
    legend.position = 'none') +
  labs(title = "Cars' Status")
  • 最终结果