Круговой график с векторами в R
Я пытаюсь создать круговую диаграмму с векторами разной величины, исходящими от начала координат под разными углами: что-то вроде изображения ниже, хотя оно не обязательно должно быть одинаковым. Я изучал circular
и circstats
и многое узнал о круговых графиках, но не нашел ничего, что мне нужно. Я думаю, что если бы мне пришлось это делать, я мог бы написать что-нибудь вручную, но, похоже, что кто-то более опытный, чем я, уже написал некоторый код для этого.
![]()
Эта цифра взята из Schmidt, 2007, Ecology 88 (11): 2793-2802, Figure 2C.
Ответы
Ответ 1
Пакет сетки очень эффективен для объединения и компоновки графических элементов.
library(grid)
Здесь результат:
Некоторые данные, я полагаю, для остальных ваших значений < 1
polar <- read.table(text ='
degree value
1 120 0.50
2 30 0.20
3 160 0.20
4 35 0.50
5 150 0.40
6 90 0.14
7 70 0.50
8 20 0.60',header=T)
## function to create axis label
axis.text <- function(col,row,text,angle){
pushViewport(viewport(layout.pos.col=col,layout.pos.row=row,just=c('top')))
grid.text(angle,vjust=0)
grid.text(text,vjust=2)
popViewport()
}
## function to create the arrows, Here I use the data
arrow.custom <- function(polar){
pushViewport(viewport(layout.pos.col=2,layout.pos.row=2))
apply(polar,1,function(x){
pushViewport(viewport(angle=x['degree']))
grid.segments(x0=0.5,y0=0.5,x1=0.5+x['value']*0.8,y1=0.5,
arrow=arrow(type='closed'),gp=gpar(fill='grey'))
popViewport()
})
popViewport()
}
## The global layout 3*3 matrix
lyt=grid.layout(3, 3,
widths= unit(c(4,15,4), "lines"),
heights=unit(c(4,15,4), "lines"),
just='center')
pushViewport(viewport(layout=lyt,xscale=2*extendrange(polar$value)))
## the central part : circles , arrows and axes
pushViewport(viewport(layout.pos.col=2,layout.pos.row=2))
grid.circle(r=c(0.5,0.3),gp = gpar(ltw=c(3,2),col=c('black','grey')))
arrow.custom(polar)
grid.segments(x0=0.5,y0=0,x1=0.5,y=1,gp=gpar(col='grey'))
grid.segments(x0=0,y0=0.5,x1=1,y=0.5,gp=gpar(col='grey'))
popViewport()
## the axis labels
axis.text(1,2,'Phragmites',expression(270 * degree))
axis.text(3,2,'Spartina',expression(90 * degree))
axis.text(2,1,'Increasing tropic position',expression(0 * degree))
axis.text(2,3,'Decreasing tropic position',expression(180 * degree))
Ответ 2
Пакет plotrix
hal hal a polar.plot
, который, кажется, делает то, что вы хотите. Однако я еще не понял, как вы могли бы добавить пунктирную линию вдоль дуги одного из краев.
Пример:
library(plotrix)
testlen<-c(rnorm(36)*2+5)
testpos<-seq(0,350,by=10)
polar.plot(testlen,testpos,main="Test Polar Plot",lwd=3,line.col=4)
#rotate degree
oldpar<-polar.plot(testlen,testpos,main="Test Clockwise Polar Plot",
start=180,clockwise=TRUE,lwd=3,line.col=4)
# reset everything
par(oldpar)
![enter image description here]()
Ответ 3
В итоге я закончил с radial.plot
в plotrix
(хотя получается, что polar.plot
имеет все те же функции - он просто не был документирован, когда я это выяснял). Я не мог понять, как делать стрелки или частичную пунктирную линию по окружности, но ни один из них не является критическим для моих целей. По какой-то причине я не смог получить первую точку данных для построения, поэтому я вставил фиктивную точку. Спасибо всем за вашу помощь!
library(plotrix)
magnitude <- c(2.1, 2.3, 2.5, 1.5, 2.8, 2.7)
angle <- c(2.1, 2.6, -0.1, -2.6, 0.1, 0.4)
directionlabels <- c("more\nbenthic", "higher trophic",
"more\npelagic", "lower trophic")
colors <- c("black", "red", "green", "blue", "orange", "purple", "pink")
par(cex.axis=0.7)
par(cex.lab=0.5)
radial.plot(c(0, magnitude),
c(0, angle),
lwd=4, line.col=,
labels=directionlabels,
radial.lim = c(0,3), #range of grid circle
main="circular diagram!",
show.grid.label=1, #put the concentric circle labels going down
show.radial.grid=TRUE
)
![circular diagram!]()
Ответ 4
Ниже представлен подход с использованием my.symbols
вместе с ms.polygon
и ms.arrows
из пакета TeachingDemos:
plot(c(-2,2),c(-2,2), axes=FALSE, xlab='', ylab='', type='n', asp=1)
abline(v=0, col='lightgrey')
abline(h=0, col='lightgrey')
my.symbols(c(0,0),c(0,0),ms.polygon, xsize=c(2,4), lwd=c(1,2), n=360)
theta <- seq(pi/4, 3*pi/4, length=250)
lines( 2.03*cos(theta), 2.03*sin(theta), lwd=2, lty='dashed' )
lines( c(0,0), c(0,2), lty='dashed', lwd=2 )
a <- c(300,305,355,0,5,45,65)
l <- c(1.1, .5, .4,1,.6,.7,1.25)
my.symbols( rep(0,7), rep(0,7), ms.arrows, xsize=2, r=l, adj=0,
angle=pi/2 - pi/180*a )