答案 0 :(得分:8)
首先,我们加载一些包。
library(reshape2)
library(ggplot2)
library(scales)
以下是您链接到的雷达图示例中的数据。
maxmin <- data.frame(
total = c(5, 1),
phys = c(15, 3),
psycho = c(3, 0),
social = c(5, 1),
env = c(5, 1)
)
dat <- data.frame(
total = runif(3, 1, 5),
phys = rnorm(3, 10, 2),
psycho = c(0.5, NA, 3),
social = runif(3, 1, 5),
env = c(5, 2.5, 4)
)
我们需要一点操作才能使它们适合ggplot。
将它们标准化,添加id列并转换为长格式。
normalised_dat <- as.data.frame(mapply(
function(x, mm)
{
(x - mm[2]) / (mm[1] - mm[2])
},
dat,
maxmin
))
normalised_dat$id <- factor(seq_len(nrow(normalised_dat)))
long_dat <- melt(normalised_dat, id.vars = "id")
ggplot还会包含值,以便第一个和最后一个因子相遇。我们添加一个额外的因子级别来避免这种情况。这不再是真的。
级别(long_dat $ variable)&lt; - c(级别(long_dat $ variable),“”)
这是情节。它不太一样,但它应该让你开始。
ggplot(long_dat, aes(x = variable, y = value, colour = id, group = id)) +
geom_line() +
coord_polar(theta = "x", direction = -1) +
scale_y_continuous(labels = percent)
请注意,使用coord_polar
时,线条会弯曲。如果你想要直线,那么你将不得不尝试不同的技术。
答案 1 :(得分:4)
如果您正在寻找非极坐标版本,我认为以下功能将有所帮助:
###################################
##Radar Plot Code
##########################################
##Assumes d is in the form:
# seg meanAcc sdAcc meanAccz sdAccz meanSpd sdSpd cluster
# 388 -0.038 1.438 -0.571 0.832 -0.825 0.095 1
##where seg is the individual instance identifier
##cluster is the cluster membership
##and the variables from meanACC to sdSpd are used for the clustering
##and thus should be individual lines on the radar plot
radarFix = function(d){
##assuming the passed in data frame
##includes only variables you would like plotted and segment label
d$seg=as.factor(d$seg)
##find increment
angles = seq(from=0, to=2*pi, by=(2*pi)/(ncol(d)-2))
##create graph data frame
graphData= data.frame(seg="", x=0,y=0)
graphData=graphData[-1,]
for(i in levels(d$seg)){
segData= subset(d, seg==i)
for(j in c(2:(ncol(d)-1))){
##set minimum value such that it occurs at 0. (center the data at -3 sd)
segData[,j]= segData[,j]+3
graphData=rbind(graphData, data.frame(seg=i,
x=segData[,j]*cos(angles[j-1]),
y=segData[,j]*sin(angles[j-1])))
}
##completes the connection
graphData=rbind(graphData, data.frame(seg=i,
x=segData[,2]*cos(angles[1]),
y=segData[,2]*sin(angles[1])))
}
graphData
}
如果您按群集或群组进行绘图,则可以使用以下内容:
radarData = ddply(clustData, .(cluster), radarFix)
ggplot(radarData, aes(x=x, y=y, group=seg))+
geom_path(alpha=0.5,colour="black")+
geom_point(alpha=0.2, colour="blue")+
facet_wrap(~cluster)
这应该适用于以下数据样本:
seg meanAccVs sdAccVs meanSpd sdSpd cluster
1470 1.420 0.433 -0.801 0.083 1
1967 -0.593 0.292 1.047 0.000 3
2167 -0.329 0.221 0.068 0.053 7
2292 -0.356 0.214 -0.588 0.056 4
2744 0.653 1.041 -1.039 0.108 5
3448 2.189 1.552 -0.339 0.057 8
7434 0.300 0.250 -1.009 0.088 5
7764 0.607 0.469 -0.035 0.078 2
7942 0.124 1.017 -0.940 0.138 5
9388 0.742 1.289 -0.477 0.301 5
答案 2 :(得分:4)
我花了几天时间讨论这个问题,最后我决定在ggradar
顶部构建my own package。它的核心是@Tony M.的功能的改进版本:
CalculateGroupPath4 <- function(df) {
angles = seq(from=0, to=2*pi, by=(2*pi)/(ncol(df)-1)) # find increment
xx<-c(rbind(t(plot.data.offset[,-1])*sin(angles[-ncol(df)]),
t(plot.data.offset[,2])*sin(angles[1])))
yy<-c(rbind(t(plot.data.offset[,-1])*cos(angles[-ncol(df)]),
t(plot.data.offset[,2])*cos(angles[1])))
graphData<-data.frame(group=rep(df[,1],each=ncol(df)),x=(xx),y=(yy))
return(graphData)
}
CalculateGroupPath5 <- function(mydf) {
df<-cbind(mydf[,-1],mydf[,2])
myvec<-c(t(df))
angles = seq(from=0, to=2*pi, by=(2*pi)/(ncol(df)-1)) # find increment
xx<-myvec*sin(rep(c(angles[-ncol(df)],angles[1]),nrow(df)))
yy<-myvec*cos(rep(c(angles[-ncol(df)],angles[1]),nrow(df)))
graphData<-data.frame(group=rep(mydf[,1],each=ncol(mydf)),x=(xx),y=(yy))
return(graphData)
}
microbenchmark::microbenchmark(CalculateGroupPath(plot.data.offset),
CalculateGroupPath4(plot.data.offset),
CalculateGroupPath5(plot.data.offset), times=1000L)
Unit: microseconds
expr min lq mean median uq max neval
CalculateGroupPath(plot.data.offset) 20768.163 21636.8715 23125.1762 22394.1955 23946.5875 86926.97 1000
CalculateGroupPath4(plot.data.offset) 550.148 614.7620 707.2645 650.2490 687.5815 15756.53 1000
CalculateGroupPath5(plot.data.offset) 577.634 650.0435 738.7701 684.0945 726.9660 11228.58 1000
请注意,我实际比较了more functions in this benchmark - 来自ggradar
的其他功能。一般来说@Tony M的解决方案写得很好 - 在逻辑意义上,你可以在许多其他语言中使用它,例如Javascript,有一些调整。但是,如果向量化操作,R
会变得更快。因此,我的解决方案大大增加了计算时间。
除了@Tony M.之外的所有答案都使用了来自coord_polar
的{{1}} - 函数。保持在笛卡尔坐标系中有四个优点:
ggplot2
。 plotly
- 包。 如果像我一样,当你找到这个线程时你对雷达图的了解一无所知:scales
可能会创造出漂亮的雷达图。然而,实施有点棘手。当我尝试它时,我遇到了多个问题:
coord_polar()
例如没有翻译成情节。此人在此nice radar-chart使用coord_polar()
。
但是根据我的经验 - 我建议不要使用coord_polar
- 技巧。相反,如果您正在寻找一种“简单方法”来创建静态ggplot雷达,可以使用伟大的coord_polar()
- 包来绘制雷达的圆圈。不能保证这比使用我的包更容易,但从适应性看起来比ggforce
更整洁。这里的缺点是例如coord_polar
不支持ggforce-extention。
编辑:现在我找到了ggplot2的coord_polar的一个很好的例子,它修改了我的观点。
答案 3 :(得分:2)
这是几乎在ggplot中做到的答案。
除了在这里举例外,我还没有提出更多要求,这是基于哈德利在这里展示的https://github.com/hadley/ggplot2/issues/516
我所做的只是使用deployer / tidyr,为简单起见只选择3辆车
尚未解决的问题是 1)最后一点和第一点没有连接,如果你看到coord_polar是传统x轴的包裹,这是显而易见的。没有理由将它们连接起来。但这就是通常显示雷达图表的方式 2)要做到这一点,你需要在这两个点之间手动添加一个段。一点点操作和更多层应该做到这一点。如果我有时间的话,我会努力工作
library(dplyr);library(tidyr);library(ggplot2)
#make some data
data = mtcars[c(27,19,16),]
data$model=row.names(data)
#connvert data to long format and also rescale it into 0-1 scales
data1 <- data %>% gather(measure,value,-model) %>% group_by(measure) %>% mutate(value1=(value-min(value))/(max(value)-min(value)))
is.linear.polar <- function(coord) TRUE
ggplot(data1,aes(x=measure,y=value1,color=model,group=model))+geom_line()+coord_polar()
答案 4 :(得分:1)
我遇到了一个很棒的库,它提供了与ggplot兼容的完美蜘蛛图:
https://github.com/ricardo-bion/ggradar
非常容易安装和使用,如您在github上所见:
devtools::install_github("ricardo-bion/ggradar", dependencies=TRUE)
library(ggradar)
suppressPackageStartupMessages(library(dplyr))
library(scales)
library(tibble)
mtcars %>%
rownames_to_column( var = "group" ) %>%
mutate_at(vars(-group),funs(rescale)) %>%
tail(4) %>% select(1:10) -> mtcars_radar
ggradar(mtcars_radar)