Закрытие линий на радарной / паучьей диаграмме ggplot2

Мне нужен гибкий способ создания диаграмм радаров / пауков в 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: Каждая группа состоит только из одного наблюдения. Вам нужно настроить эстетику группы?"

Сообщения. Сом, как мне закрыть очереди?

/ Фредрик


person Fredrik Karlsson    schedule 06.03.2015    source источник
comment
ggplot(mtcarsm[mtcarsm$model == "Maserati Bora", ], aes(x = variable, y = value)) + geom_path(aes(group = model)) + coord_radar() закрывает строки здесь.   -  person lukeA    schedule 06.03.2015
comment
Теперь я запуталась. Выполнение кода, который вы опубликовали, для меня ясно показывает разрыв между mpg и carb. Что здесь происходит?   -  person Fredrik Karlsson    schedule 07.03.2015
comment
Забудьте упомянуть: закрывает строку для фрейма данных rbinded.   -  person lukeA    schedule 07.03.2015


Ответы (6)


Используя новый механизм ggproto, доступный в ggplot2 2.0.0, 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)
}

Не уверен, что синтаксис идеален, но он работает ...

person Erwan LE PENNEC    schedule 30.12.2015
comment
Через некоторое время проблема снова возникает, и это решение не работает для ggplot2 v. 3.3.0 ,,, - person aGricolaMZ; 25.05.2020

Коды здесь кажутся устаревшими для 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

введите описание изображения здесь  введите описание изображения здесь

person Jerry T    schedule 15.02.2016
comment
добавляет ли ваш пакет функциональность по сравнению с кодом, на который вы ссылаетесь? Или это просто быстрый доступ к таким же сюжетам? - person PatrickT; 19.04.2016
comment
У меня другой алгоритм масштабирования, и я также конвертирую формат данных в длинный формат, который требуется для ggplot2. - person Jerry T; 20.04.2016

  • solution key factor
    1. add duplicated mpg row after melt by rbind
    2. унаследовать CoordPolar от ggproto
    3. установить is_linear = function() TRUE на ggproto

особенно 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")
  • окончательный результат
     введите описание изображения здесь
person Curycu    schedule 29.12.2017

Извини, я был глупым. Кажется, это работает:

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))) 
person Fredrik Karlsson    schedule 09.03.2015

Оказывается, 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("")

отлично работает ...

person Erwan LE PENNEC    schedule 01.06.2015
comment
Да, но я думаю, что больше всего хотелось бы видеть прямые линии между точками на графике (а не пузыри). Мне больше нравится вывод решения corre_radar ниже. - person Fredrik Karlsson; 05.06.2015

Спасибо, ребята, за помощь, но она не покрыла все мои потребности. Я использовал две серии данных для сравнения, поэтому я взял подмножество автомобилей Mazda:

  1. никто не упомянул о порядке переменной x, и ggplot2 сортирует эту переменную для графика, но не сортирует данные, и это сделало мою диаграмму неправильной с первой попытки. Примените функцию сортировки, для меня это было dplyr :: аранжировка (plot.data, x.variable.name)

  2. Мне нужно было аннотировать диаграмму значениями, и ggplot2 :: annotate () отлично работает, но он не был включен в недавние ответы

  3. приведенный выше код не работал с моими данными до тех пор, пока не добавили ggplot2 :: geom_line

Наконец, этот фрагмент кода сделал мою диаграмму:

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()

Надеюсь, полезно для кого-то

person Agnieszka    schedule 24.05.2016