R base graphics circular histogram

∥☆過路亽.° 提交于 2020-02-24 14:08:27

问题


What would be the best way to draw a circular histogram in R?

My data has this form:

    Dir      N
 1: 360  56564
 2:   0     NA
 3: 180 149374
 4: 210  82219
 5: 240  23315
 6: 300  11436
 7: 330  30648
 8:  30  32198
 9:  60  15266
10:  90  14596
11: 120  26267
12: 150  81782
13: 270  10100

I have tried using windrose function from the circular package but it requires input data in another format.

I have looked into the graphics:: functions and stars looked promising, but nothing concrete so far.

Thanks


回答1:


You can try the following with circular, but since your data size is small, the plot is not very fancy:

library(circular)
df <- read.table(text='Dir      N
 1: 360  56564
 2:   0     NA
 3: 180 149374
 4: 210  82219
 5: 240  23315
 6: 300  11436
 7: 330  30648
 8:  30  32198
 9:  60  15266
10:  90  14596
11: 120  26267
12: 150  81782
13: 270  10100', header=TRUE)
rownames(df) <- NULL
names(df) <- c('dir', 'mag')
df$dir <- circular(as.numeric(df$dir), units='degrees')
df$mag <- df$mag / 10000 # scale magnitude
windrose(df, breaks=circular(seq(0, 2 * pi, by = pi/4)), increment=5)

With another library openair it looks like the following:

library(openair)
df <- read.table(text='Dir      N
     1: 360  56564
     2:   0     NA
     3: 180 149374
     4: 210  82219
     5: 240  23315
     6: 300  11436
     7: 330  30648
     8:  30  32198
     9:  60  15266
    10:  90  14596
    11: 120  26267
    12: 150  81782
    13: 270  10100', header=TRUE)
names(df) <- c('wd', 'ws')
df$ws <- df$ws / 10000 # scale speed
windRose(df, angle=45)

The polar coord plot with ggplot2 looks different (which just converts geom_bar into polar coordinates)

library(ggplot2)
ggplot(df, aes(x=dir, y=mag)) + geom_bar(stat='identity') + coord_polar()

Some implementation I tried in base R from scratch (just for the idea, the implementation is not very efficient, you can always improve the efficiency of implementation, for example use polygon instead of segments to fill the arcs), we can use a similar implementation in base R to mimic the one in ggplot:

add.filled.arc <- function(center.x, center.y, radius, angle.start, angle.end, col='black') {
  theta <- seq(angle.start, angle.end, .0001)
  segments(0, 0, radius*cos(theta), radius*sin(theta), col)
  segments(0, 0, cos(angle.start), sin(angle.start), col='gray')
  segments(0, 0, cos(angle.end), sin(angle.end), col='gray')
}

plot.coord.polar <- function(df) {
  df <- df[complete.cases(df),]
  df <- df[order(df[,1]),]
  df[,1] <- df[,1]*(pi/180) # convert dir to radian
  df[,2] <- df[,2] / max(df[,2]) # normalize magnitude within [0-1]
  plot(-1:1, -1:1, type= 'n', xlab='', ylab='', xaxt='n', yaxt='n')
  sapply(1:(nrow(df)-1), function(i) add.filled.arc(0, 0, df[i,2], df[i,1], df[i+1,1], rainbow(nrow(df))[i]))
  theta <- seq(0, 2*pi, 0.0001)
  lines(cos(theta), sin(theta), col='gray')
}

df <- read.table(text='Dir      N
                 1: 360  56564
                 2:   0     NA
                 3: 180 149374
                 4: 210  82219
                 5: 240  23315
                 6: 300  11436
                 7: 330  30648
                 8:  30  32198
                 9:  60  15266
                 10:  90  14596
                 11: 120  26267
                 12: 150  81782
                 13: 270  10100', header=TRUE)
plot.coord.polar(df)




回答2:


You could use ggplot2:

library(ggplot2)
data(mpg)
g <- ggplot(mpg, aes(class)) + geom_bar() + coord_polar()
g

For your data, assuming your data frame above is called df, and you want to graph N you would do:

library(ggplot2)
g <- ggplot(df, aes(N)) + geom_bar() + coord_polar()
g


来源:https://stackoverflow.com/questions/41627124/r-base-graphics-circular-histogram

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!