ggplot (R) 随风升起? [英] Wind rose with ggplot (R)?

查看:20
本文介绍了ggplot (R) 随风升起?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找使用 ggplot2 创建风玫瑰的优秀 R 代码(或包)显示风的频率、大小和方向.

I am looking for good R code (or package) that uses ggplot2 to create wind roses that show the frequency, magnitude and direction of winds.

我对 ggplot2 特别感兴趣,因为以这种方式构建绘图让我有机会利用那里的其余功能.

I'm particularly interested in ggplot2 as building the plot that way gives me the chance to leverage the rest of the functionality in there.

National Wind Technology 的M2"上下载 80 米级别的一年天气数据 塔.此链接 将创建一个自动下载的 .csv 文件.您需要找到该文件(名为20130101.csv"),然后读入.

Download a year of weather data from the 80-m level on the National Wind Technology's "M2" tower. This link will create a .csv file that is automatically downloaded. You need to find that file (it's called "20130101.csv"), and read it in.

# read in a data file
data.in <- read.csv(file = "A:/drive/somehwere/20130101.csv",
                    col.names = c("date","hr","ws.80","wd.80"),
                    stringsAsFactors = FALSE))

这适用于任何 .csv 文件,并将覆盖列名称.

This would work with any .csv file and will overwrite the column names.

如果您不想下载该数据,我们将使用以下 10 个数据点来演示该过程:

If you don't want to download that data, here are 10 data points that we will use to demo the process:

data.in <- structure(list(date = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 

1L, 1L), .Label = "1/1/2013", class = "factor"), hr = 1:9, ws.80 = c(5,7, 7, 51.9, 11, 12, 9, 11, 17), wd.80 = c(30, 30, 30, 180, 180,180, 269, 270, 271)), .Names = c("date", "hr", "ws.80", "wd.80"), row.names = c(NA, -9L), class = "data.frame")

1L, 1L), .Label = "1/1/2013", class = "factor"), hr = 1:9, ws.80 = c(5, 7, 7, 51.9, 11, 12, 9, 11, 17), wd.80 = c(30, 30, 30, 180, 180, 180, 269, 270, 271)), .Names = c("date", "hr", "ws.80", "wd.80" ), row.names = c(NA, -9L), class = "data.frame")

推荐答案

为了论证起见,我们假设我们使用的是 data.in 数据框,它有两个数据列和一些一种日期/时间信息.我们最初会忽略日期和时间信息.

For sake of argument we'll assume that we are using the data.in data frame, which has two data columns and some kind of date / time information. We'll ignore the date and time information initially.

我已经对下面的函数进行了编码.我对其他人的经验或如何改进这一点的建议很感兴趣.

I've coded the function below. I'm interested in other people's experience or suggestions on how to improve this.

# WindRose.R
require(ggplot2)
require(RColorBrewer)

plot.windrose <- function(data,
                      spd,
                      dir,
                      spdres = 2,
                      dirres = 30,
                      spdmin = 2,
                      spdmax = 20,
                      spdseq = NULL,
                      palette = "YlGnBu",
                      countmax = NA,
                      debug = 0){


# Look to see what data was passed in to the function
  if (is.numeric(spd) & is.numeric(dir)){
    # assume that we've been given vectors of the speed and direction vectors
    data <- data.frame(spd = spd,
                       dir = dir)
    spd = "spd"
    dir = "dir"
  } else if (exists("data")){
    # Assume that we've been given a data frame, and the name of the speed 
    # and direction columns. This is the format we want for later use.    
  }  

  # Tidy up input data ----
  n.in <- NROW(data)
  dnu <- (is.na(data[[spd]]) | is.na(data[[dir]]))
  data[[spd]][dnu] <- NA
  data[[dir]][dnu] <- NA

  # figure out the wind speed bins ----
  if (missing(spdseq)){
    spdseq <- seq(spdmin,spdmax,spdres)
  } else {
    if (debug >0){
      cat("Using custom speed bins 
")
    }
  }
  # get some information about the number of bins, etc.
  n.spd.seq <- length(spdseq)
  n.colors.in.range <- n.spd.seq - 1

  # create the color map
  spd.colors <- colorRampPalette(brewer.pal(min(max(3,
                                                    n.colors.in.range),
                                                min(9,
                                                    n.colors.in.range)),                                               
                                            palette))(n.colors.in.range)

  if (max(data[[spd]],na.rm = TRUE) > spdmax){    
    spd.breaks <- c(spdseq,
                    max(data[[spd]],na.rm = TRUE))
    spd.labels <- c(paste(c(spdseq[1:n.spd.seq-1]),
                          '-',
                          c(spdseq[2:n.spd.seq])),
                    paste(spdmax,
                          "-",
                          max(data[[spd]],na.rm = TRUE)))
    spd.colors <- c(spd.colors, "grey50")
  } else{
    spd.breaks <- spdseq
    spd.labels <- paste(c(spdseq[1:n.spd.seq-1]),
                        '-',
                        c(spdseq[2:n.spd.seq]))    
  }
  data$spd.binned <- cut(x = data[[spd]],
                         breaks = spd.breaks,
                         labels = spd.labels,
                         ordered_result = TRUE)
  # clean up the data
  data. <- na.omit(data)

  # figure out the wind direction bins
  dir.breaks <- c(-dirres/2,
                  seq(dirres/2, 360-dirres/2, by = dirres),
                  360+dirres/2)  
  dir.labels <- c(paste(360-dirres/2,"-",dirres/2),
                  paste(seq(dirres/2, 360-3*dirres/2, by = dirres),
                        "-",
                        seq(3*dirres/2, 360-dirres/2, by = dirres)),
                  paste(360-dirres/2,"-",dirres/2))
  # assign each wind direction to a bin
  dir.binned <- cut(data[[dir]],
                    breaks = dir.breaks,
                    ordered_result = TRUE)
  levels(dir.binned) <- dir.labels
  data$dir.binned <- dir.binned

  # Run debug if required ----
  if (debug>0){    
    cat(dir.breaks,"
")
    cat(dir.labels,"
")
    cat(levels(dir.binned),"
")       
  }  

  # deal with change in ordering introduced somewhere around version 2.2
  if(packageVersion("ggplot2") > "2.2"){    
    cat("Hadley broke my code
")
    data$spd.binned = with(data, factor(spd.binned, levels = rev(levels(spd.binned))))
    spd.colors = rev(spd.colors)
  }

  # create the plot ----
  p.windrose <- ggplot(data = data,
                       aes(x = dir.binned,
                           fill = spd.binned)) +
    geom_bar() + 
    scale_x_discrete(drop = FALSE,
                     labels = waiver()) +
    coord_polar(start = -((dirres/2)/360) * 2*pi) +
    scale_fill_manual(name = "Wind Speed (m/s)", 
                      values = spd.colors,
                      drop = FALSE) +
    theme(axis.title.x = element_blank())

  # adjust axes if required
  if (!is.na(countmax)){
    p.windrose <- p.windrose +
      ylim(c(0,countmax))
  }

  # print the plot
  print(p.windrose)  

  # return the handle to the wind rose
  return(p.windrose)
}

概念和逻辑证明

我们现在将检查代码是否符合我们的预期.为此,我们将使用一组简单的演示数据.

Proof of Concept and Logic

We'll now check that the code does what we expect. For this, we'll use the simple set of demo data.

# try the default settings
p0 <- plot.windrose(spd = data.in$ws.80,
                   dir = data.in$wd.80)

这给了我们这个情节:所以:我们已经按照方向和风速正确地对数据进行了分类,并按照预期对我们的超出范围的数据进行了编码.看起来不错!

This gives us this plot: So: we've correctly binned the data by direction and wind speed, and have coded up our out-of-range data as expected. Looks good!

现在我们加载真实数据.我们可以从 URL 加载它:

Now we load the real data. We can load this from the URL:

data.in <- read.csv(file = "http://midcdmz.nrel.gov/apps/plot.pl?site=NWTC&start=20010824&edy=26&emo=3&eyr=2062&year=2013&month=1&day=1&endyear=2013&endmonth=12&endday=31&time=0&inst=21&inst=39&type=data&wrlevel=2&preset=0&first=3&math=0&second=-1&value=0.0&user=0&axis=1",
                    col.names = c("date","hr","ws.80","wd.80"))

或来自文件:

data.in <- read.csv(file = "A:/blah/20130101.csv",
                    col.names = c("date","hr","ws.80","wd.80"))

快捷方式

将其与 M2 数据一起使用的简单方法是为 spddir(速度和方向)传入单独的向量:

The quick way

The simple way to use this with the M2 data is to just pass in separate vectors for spd and dir (speed and direction):

# try the default settings
p1 <- plot.windrose(spd = data.in$ws.80,
                   dir = data.in$wd.80)

这给了我们这个情节:

如果我们想要自定义 bins,我们可以将它们添加为参数:

And if we want custom bins, we can add those as arguments:

p2 <- plot.windrose(spd = data.in$ws.80,
                   dir = data.in$wd.80,
                   spdseq = c(0,3,6,12,20))

为了使绘图与ggplot()更加兼容,您还可以传入一个数据框以及速度和方向变量的名称:

To make the plots more compatible with ggplot(), you can also pass in a data frame and the name of the speed and direction variables:

p.wr2 <- plot.windrose(data = data.in,
              spd = "ws.80",
              dir = "wd.80")

面对另一个变量

我们还可以使用 ggplot 的分面功能按月或按年绘制数据.我们先从data.in中的日期和小时信息中获取时间戳,并转换为月份和年份:

Faceting by another variable

We can also plot the data by month or year using ggplot's faceting capability. Let's start by getting the time stamp from the date and hour information in data.in, and converting to month and year:

# first create a true POSIXCT timestamp from the date and hour columns
data.in$timestamp <- as.POSIXct(paste0(data.in$date, " ", data.in$hr),
                                tz = "GMT",
                                format = "%m/%d/%Y %H:%M")

# Convert the time stamp to years and months 
data.in$Year <- as.numeric(format(data.in$timestamp, "%Y"))
data.in$month <- factor(format(data.in$timestamp, "%B"),
                        levels = month.name)

然后您可以应用分面来显示风上升如何随月变化:

Then you can apply faceting to show how the wind rose varies by month:

# recreate p.wr2, so that includes the new data
p.wr2 <- plot.windrose(data = data.in,
              spd = "ws.80",
              dir = "wd.80")
# now generate the faceting
p.wr3 <- p.wr2 + facet_wrap(~month,
                            ncol = 3)
# and remove labels for clarity
p.wr3 <- p.wr3 + theme(axis.text.x = element_blank(),
          axis.title.x = element_blank())

关于该函数及其使用方法的一些注意事项:

Some things to note about the function and how it can be used:

  • 输入是:
    • 速度向量(spd)和方向(dir)数据框的名称和包含的列的名称速度和方向数据.
    • 风速 (spdres) 和方向 (dirres) 的 bin 大小的可选值.
    • palettecolorbrewer 连续调色板的名称,
    • countmax 设置风玫瑰的范围.
    • debug 是一个开关 (0,1,2),用于启用不同级别的调试.
    • The inputs are:
      • vectors of speed (spd) and direction (dir) or the name of the data frame and the names of the columns that contain the speed and direction data.
      • optional values of the bin size for wind speed (spdres) and direction (dirres).
      • palette is the name of a colorbrewer sequential palette,
      • countmax sets the range of the wind rose.
      • debug is a switch (0,1,2) to enable different levels of debugging.

      这篇关于ggplot (R) 随风升起?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆