ggplot (R) で風配図を作成する? 質問する

ggplot (R) で風配図を作成する? 質問する

ggplot2を使って作成する良いRコード(またはパッケージ)を探しています風のバラ風の頻度、強さ、方向を示します。

私は ggplot2 に特に興味があります。そのようにプロットを構築すると、そこにある残りの機能を活用できるからです。

テストデータ

80mレベルから1年間の気象データをダウンロードナショナル・ウィンド・テクノロジーの「M2」タワー。このリンク自動的にダウンロードされる .csv ファイルが作成されます。そのファイル (「20130101.csv」という名前) を見つけて読み込む必要があります。

# 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 ファイルで機能し、列名を上書きします。

サンプルデータ

データをダウンロードしたくない場合は、プロセスのデモに使用する 10 個のデータ ポイントを以下に示します。

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

ベストアンサー1

説明のために、data.in2 つのデータ列と何らかの日付/時刻情報を持つデータ フレームを使用していると仮定します。最初は日付と時刻の情報は無視します。

ggplot関数

以下の関数をコーディングしました。他の人の経験や、これを改善する方法についての提案に興味があります。

# 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 \n")
    }
  }
  # 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,"\n")
    cat(dir.labels,"\n")
    cat(levels(dir.binned),"\n")       
  }  

  # deal with change in ordering introduced somewhere around version 2.2
  if(packageVersion("ggplot2") > "2.2"){    
    cat("Hadley broke my code\n")
    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)
}

概念とロジックの証明

ここで、コードが期待どおりに動作するか確認します。そのために、簡単なデモ データ セットを使用します。

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

これにより、次のプロットが得られます。ユニットテストの結果つまり、方向と風速によってデータを正しく分類し、範囲外のデータを期待どおりにコード化しました。よさそうです!

この機能を使う

ここで実際のデータをロードします。これは 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 データで使用する簡単な方法は、spd速度dirと方向の別々のベクトルを渡すことです。

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

すると次の図が得られます。

ここに画像の説明を入力してください

カスタムビンが必要な場合は、それを引数として追加できます。

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

ここに画像の説明を入力してください

データフレームと列名の使用

プロットを とより互換性のあるものにするためにggplot()、データフレームを渡すこともできます。名前速度と方向の変数:

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

別の変数によるファセット

ggplot のファセット機能を使用して、データを月別または年別にプロットすることもできます。まず、 の日付と時刻の情報からタイムスタンプを取得しdata.in、月と年に変換してみましょう。

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

次に、ファセットを適用して、風の配図が月ごとにどのように変化するかを示します。

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

ここに画像の説明を入力してください

コメント

この機能とその使用方法について注意すべき点は次のとおりです。

  • 入力内容は次のとおりです。
    • 速度(spd)と方向(dir)のベクトルまたはデータフレームの名前と、速度と方向のデータを含む列の名前。
    • spdres風速( )と風向( )のビンサイズのオプション値dirres
    • paletteの名前ですカラーブリューワー連続パレット、
    • countmax風配図の範囲を設定します。
    • debug異なるレベルのデバッグを有効にするスイッチ (0,1,2) です。
  • 異なるデータセットの風向風速を比較できるように、プロットの最大速度( spdmax)とカウント( )を設定できるようにしたいと考えました。countmax
  • ( )を超える風速がある場合はspdmax、灰色の領域として追加されます(図を参照)。 のようなコードも記述しspdmin、風速がそれより低い領域を色分けする必要があると思います。
  • リクエストに応じて、カスタム風速ビンを使用するメソッドを実装しました。spdseq = c(1,3,5,12)引数を使用して追加できます。
  • 通常の ggplot コマンドを使用して度数ビンのラベルを削除し、x 軸をクリアすることができますp.wr3 + theme(axis.text.x = element_blank(),axis.title.x = element_blank())
  • 最近、ggplot2 がビンの順序を変更したため、プロットが機能しなくなりました。これはバージョン 2.2 だったと思います。ただし、プロットが少し変に見える場合は、コードを変更して、「2.2」のテストを「2.1」または「2.0」にしてください。

おすすめ記事