Rで解析:スパイラルチャートを手軽に作成!「spiralize」パッケージ

Rの解析に役に立つ記事
スポンサーリンク

スパイラルチャートを手軽に作成できるパッケージの紹介です。よく使いそうなコマンドと気象庁からダウンロードできる札幌の気温データを使用した例を紹介します。

スパイラルチャートはアルキメデスの螺旋に沿ってプロットし表現する手法で、大規模なデータを視認するのに便利です。Spiral PlotやSpiral chartsで検索していただくと多くの情報を得ることが可能です。

パッケージバージョンは1.0.4。windows11のR version 4.1.2で確認しています。

スポンサーリンク

パッケージのインストール

下記、コマンドを実行してください。

#パッケージのインストール
install.packages("spiralize")

実行コマンド

詳細はコメント、コマンドヘルプを確認してください。

###基本的な設定#####
#スパイラルチャートの設定:spiral_initializeコマンド
#チャートの開始点:startオプション
#チャートの終了点:endオプション
#start,endオプションは[360x + b]で直感的に設定できます
#反転の設定:flipオプション;"none","horizontal","vertical","both"
#データスケーリング設定:scale_byオプション
###"angle":極座標からの角度の差が等しくする
###"curve":スパイラルチャートにデータが収まるようにする
#データ軸の方向を設定:reverseオプション;TRUE,FALSE
#x軸範囲を指定:xlimオプション;c(min, max)
spiral_initialize(start = 360*1 + 0, end = 360*3 + 180,
                  flip = "none", scale_by = "angle",
                  reverse = FALSE, xlim = sRange)

#スパイラルチャートのトラック設定:spiral_trackコマンド
#トラックの幅を設定:heightオプション;0:1の範囲
#y軸範囲を指定:reverse_yオプション;c(min, max)
#データ軸の方向を設定:reverse_yオプション;TRUE,FALSE
#トラックの枠,塗色:background_gpオプション;gparコマンドで指定
spiral_track(height = 0.4, ylim = c(0, 1),
             background_gp = gpar(col = "green", fill = 2))
#トラックは重ねることができます
spiral_track(height = 0.4, ylim = c(0, 1),
             background_gp = gpar(col = "red", fill = "yellow"))

#x軸の設定:spiral_axisコマンド
#ラベルの位置:hオプション;"top","bottom"
#ラベルをカーブで曲げる:curved_labelsオプション;TRUE,FALSE
#フォントサイズを設定:labels_gpオプション;gparコマンドで指定
spiral_axis(h = "top", curved_labels = TRUE,
            labels_gp = gpar(fontsize = 7))

#y軸の設定:spiral_yaxisコマンド
#ラベルの位置:sideオプション;"both","start","end"
spiral_yaxis(side = "both")

###参考#####
#スパイラルチャートのトラック数を確認:n_tracksコマンド
n_tracks()
[1] 2

#アクティブなスパイラルチャートのトラックを変更:set_current_trackコマンド
#スパイラルトラックを指定:track_index
set_current_track(track_index = 2)

#現在のアクティブなスパイラルチャートのトラック確認:current_track_indexコマンド
current_track_index()
[1] 2
########

各種スパイラルチャート例

詳細はコメント、コマンドヘルプを確認してください。

###各種スパイラルチャート例#####
#各種スパイラルチャート例で使う基本プロットを作成
BasePlot <- function(){
  #&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12398;&#35373;&#23450;
  spiral_initialize(start = 360*1 + 0, end = 360*3 + 180,
                      flip = "none", scale_by = "angle",
                      reverse = FALSE, xlim = sRange)
  #&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12398;&#12488;&#12521;&#12483;&#12463;&#35373;&#23450;
  spiral_track(height = 0.7, ylim = c(0, 1),
               background_gp = gpar(col = "#426617", fill = "#deb7a0"))
  #x&#36600;&#12398;&#35373;&#23450;
  spiral_axis(h = "top", curved_labels = TRUE,
              labels_gp = gpar(fontsize = 7))
  #y&#36600;&#12398;&#35373;&#23450;
  spiral_yaxis(side = "both")
    }

#&#30906;&#35469;
BasePlot()
#&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12479;&#12452;&#12488;&#12523;
grid.text("&#22522;&#26412;&#12503;&#12525;&#12483;&#12488;", x = 0, y = 1, just = c("left", "top"))


#&#25955;&#24067;&#22259;&#12398;&#25551;&#20889;:spiral_points&#12467;&#12510;&#12531;&#12489;
BasePlot()
spiral_points(x = seq(max, min, length = 10), y = ValueRunif,
              pch = 16, gp = gpar(cex = 2, col = "#94bbe3"))
#&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12479;&#12452;&#12488;&#12523;
grid.text("spiral_points&#12467;&#12510;&#12531;&#12489;", x = 0, y = 1, just = c("left", "top"))

#&#25240;&#12428;&#32218;&#12464;&#12521;&#12501;&#12398;&#25551;&#20889;:spiral_lines&#12467;&#12510;&#12531;&#12489;
#&#12456;&#12522;&#12450;&#12434;&#22615;&#12426;&#12388;&#12406;&#12375;:area&#12458;&#12503;&#12471;&#12519;&#12531;;TRUE,FALSE
BasePlot()
spiral_lines(x = seq(max, min, length = 10), y = ValueRunif,
             area = TRUE, type = "l",
             gp = gpar(lwd = 3, fill = "#94bbe3",
                       col = "#bfe6d5", alpha = 1))
#&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12479;&#12452;&#12488;&#12523;
grid.text("spiral_lines&#12467;&#12510;&#12531;&#12489;", x = 0, y = 1, just = c("left", "top"))
#&#21442;&#32771;:&#36600;&#12395;&#27700;&#24179;&#12391;&#12503;&#12525;&#12483;&#12488;
#spiral_lines(x = seq(max, min, length = 10), y = runif(10),
#             type = "h", gp = gpar(lwd = 3, col = "red"))


#&#12475;&#12464;&#12513;&#12531;&#12488;&#12434;&#25551;&#20889;:spiral_segments&#12467;&#12510;&#12531;&#12489;
#&#30690;&#21360;&#12395;&#12377;&#12427;:arrow&#12458;&#12503;&#12471;&#12519;&#12531;
BasePlot()
spiral_segments(x0 = ValueRunif,
                y0 = ValueRunif,
                x1 = ValueRunif + runif(10, min = -0.02, max = 0.02),
                y1 = 0.9 - ValueRunif, arrow = arrow(length = unit(2, "mm")),
                gp = gpar(col = circlize::rand_color(10, luminosity = "bright"),
                          lwd = 2))
#&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12479;&#12452;&#12488;&#12523;
grid.text("spiral_segments&#12467;&#12510;&#12531;&#12489;", x = 0, y = 1, just = c("left", "top"))

#&#26834;&#12464;&#12521;&#12501;&#12398;&#25551;&#20889;:spiral_bars&#12467;&#12510;&#12531;&#12489;
#&#26834;&#12464;&#12521;&#12501;&#12398;&#38283;&#22987;&#22522;&#28310;&#12434;&#25351;&#23450;:baseline&#12458;&#12503;&#12471;&#12519;&#12531;
BasePlot()
spiral_bars(pos = seq(0.3, 0.9, length = 10),
            value = ValueRunif, baseline = 0,
            gp = gpar(fill = ifelse(ValueRunif > 0.5, "#bfe6d5", "#94bbe3"), col = NA))
#&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12479;&#12452;&#12488;&#12523;
grid.text("spiral_bars&#12467;&#12510;&#12531;&#12489;", x = 0, y = 1, just = c("left", "top"))

#&#12486;&#12461;&#12473;&#12488;&#12398;&#25551;&#20889;:spiral_text&#12467;&#12510;&#12531;&#12489;
#&#25551;&#20889;&#26041;&#27861;&#12398;&#25351;&#23450;:facing&#12458;&#12503;&#12471;&#12519;&#12531;;"downward","inside","outside",
#"clockwise","reverse_clockwise","curved_inside","curved_outside"
BasePlot()
spiral_text(x = seq(0.3, 0.9, length = 10), y = 0.5,
            "&#12363;&#12425;&#12384;&#12395;&#12356;&#12356;&#12418;&#12398;", facing = "curved_inside",
            gp = gpar(col = "#426617", alpha = 1))
#&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12479;&#12452;&#12488;&#12523;
grid.text("spiral_text&#12467;&#12510;&#12531;&#12489;", x = 0, y = 1, just = c("left", "top"))

#&#36600;&#12521;&#12505;&#12523;&#12398;&#36861;&#21152;:spiral_axis&#12467;&#12510;&#12531;&#12489;
BasePlot()
spiral_axis(major_at = seq(0, 1, length = 13),
            labels = c("", month.name), minor_ticks = 6,
            labels_gp = gpar(fontsize = 10, col = "red"))
#&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12479;&#12452;&#12488;&#12523;
grid.text("spiral_axis&#12467;&#12510;&#12531;&#12489;", x = 0, y = 1, just = c("left", "top"))

#&#30690;&#21360;&#12398;&#25551;&#20889;:spiral_arrow&#12467;&#12510;&#12531;&#12489;
#&#30690;&#21360;&#26411;&#31471;&#12398;&#24418;&#29366;:tail&#12458;&#12503;&#12471;&#12519;&#12531;;"normal","point"
#&#30690;&#21360;&#12398;&#38283;&#22987;&#26041;&#21521;:arrow_position;"end","start"
#&#30690;&#21360;&#20808;&#38957;&#12398;&#24133;:arrow_head_width&#12458;&#12503;&#12471;&#12519;&#12531;
#&#30690;&#21360;&#20808;&#38957;&#12398;&#38263;&#12373;:arrow_head_length&#12458;&#12503;&#12471;&#12519;&#12531;
BasePlot()
spiral_arrow(0.68, 0.78, tail = "point", arrow_position = "start",
             arrow_head_width = 2, arrow_head_length = unit(4, "mm"),
             gp = gpar(fill = "#bfe6d5", col = NA))
#&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12479;&#12452;&#12488;&#12523;
grid.text("spiral_arrow&#12467;&#12510;&#12531;&#12489;", x = 0, y = 1, just = c("left", "top"))

#&#30011;&#20687;&#12434;&#25551;&#20889;:spiral_raster&#12467;&#12510;&#12531;&#12489;
#&#12503;&#12525;&#12483;&#12488;&#26041;&#27861;&#12398;&#25351;&#23450;:facing&#12458;&#12503;&#12471;&#12519;&#12531;;"downward","inside","outside",
#"curved_inside","curved_outside"
#&#30011;&#20687;&#12398;&#35501;&#12415;&#36796;&#12415;
image <- system.file("extdata", "Rlogo.png", package = "circlize")
BasePlot()
spiral_raster(x = 0.3, y = 0.4, image, width = 0.05, height = 1,
              facing = "curved_inside", nice_facing = TRUE)

#&#25351;&#23450;&#12456;&#12522;&#12450;&#12434;&#22615;&#12426;&#12388;&#12406;&#12375;:spiral_highlight_by_sector&#12467;&#12510;&#12531;&#12489;
BasePlot()
spiral_highlight_by_sector(x1 = 0.1, x2 = 0.12, x3 = 0.45, x4 = 0.48,
                           gp = gpar(fill = "black"))
#&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12479;&#12452;&#12488;&#12523;
grid.text("spiral_highlight_by_sector&#12467;&#12510;&#12531;&#12489;",
          x = 0, y = 1, just = c("left", "top"))

#&#26085;&#20184;&#36600;&#12398;&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12434;&#20316;&#25104;:spiral_initialize_by_time&#12467;&#12510;&#12531;&#12489;
#spiral_track&#12392;spiral_axis&#12467;&#12510;&#12531;&#12489;&#12392;&#32068;&#12415;&#21512;&#12431;&#12379;&#12390;&#20351;&#29992;&#12375;&#12414;&#12377;&#12290;
#&#35443;&#32048;&#12399;&#12504;&#12523;&#12503;&#12434;&#30906;&#35469;&#12375;&#12390;&#12367;&#12384;&#12373;&#12356;
spiral_initialize_by_time(xlim = c("2014-01-01", "2021-06-17"))
spiral_track(height = 0.6)
spiral_axis()
#&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12479;&#12452;&#12488;&#12523;
grid.text("spiral_initialize_by_time&#12467;&#12510;&#12531;&#12489;",
          x = 0, y = 1, just = c("left", "top"))

出力例

札幌の気温データを使用した例

気象庁HP:https://www.data.jma.go.jp/gmd/risk/obsdl/より札幌の気温データを取得・加工してプロットした例です。パソコンの性能によってはプロットに時間がかかります。

なお、ComplexHeatmapパッケージはBioconductorからインストールします。

使用したcsvデータは以下よりダウンロードできます。

#&#12497;&#12483;&#12465;&#12540;&#12472;&#12398;&#35501;&#12415;&#36796;&#12415;
library("tcltk")
library("spiralize")
if(!require("tidyverse", quietly = TRUE)){
  install.packages("tidyverse");require("tidyverse")}
if(!require("lubridate", quietly = TRUE)){
  install.packages("lubridate");require("lubridate")}
if(!require("cowplot", quietly = TRUE)){
  install.packages("cowplot");require("cowplot")}
if(!require("BiocManager", quietly = TRUE)){
  install.packages("BiocManager");require("BiocManager")}
if(!require("ComplexHeatmap", quietly = TRUE)){
  BiocManager::install("ComplexHeatmap");require("ComplexHeatmap")}

###&#12487;&#12540;&#12479;&#12398;&#28310;&#20633;#####
#&#27671;&#35937;&#24193;HP:https://www.data.jma.go.jp/gmd/risk/obsdl/&#12424;&#12426;&#26413;&#24140;&#12398;&#27671;&#28201;&#12487;&#12540;&#12479;&#12434;&#21462;&#24471;&#12539;&#21152;&#24037;
#&#27671;&#28201;&#12487;&#12540;&#12479;&#12399;26298*3&#12398;&#12469;&#12452;&#12474;
#SapporoTemp.csv&#12434;&#36984;&#25246;
FilePath <- paste0(as.character(tkgetOpenFile(title = "&#12501;&#12449;&#12452;&#12523;&#12434;&#36984;&#25246;",
                                              filetypes = '{"&#12501;&#12449;&#12452;&#12523;" {".csv"}}',
                                              initialfile = c("*.*"))), collapse = " ")
#&#35501;&#12415;&#36796;&#12415;
ReadData <- read.csv(FilePath)

#&#27424;&#25613;&#20516;&#12434;0&#12395;&#32622;&#12365;&#25563;&#12360;,&#24180;&#26376;&#26085;&#12391;&#25277;&#20986;
AnaData <- ReadData %>%
  mutate_if(is.numeric, ~replace(., is.na(.), 0)) %>%
  mutate(Date = ymd(Date)) %>%
  filter(Date >= "1950-01-01" & Date <= "2000-12-31")
########

#cowplot&#12497;&#12483;&#12465;&#12540;&#12472;&#12391;&#12503;&#12525;&#12483;&#12488;&#12377;&#12427;&#12383;&#12417;&#12395;&#31354;list&#12434;&#20316;&#25104;
PlotList <- list()

#cowplot&#12497;&#12483;&#12465;&#12540;&#12472;&#12391;spiralize&#12497;&#12483;&#12465;&#12540;&#12472;&#12398;&#12456;&#12521;&#12540;&#12434;&#34920;&#31034;&#12375;&#12394;&#12356;
spiral_opt$help = FALSE

#&#26368;&#39640;&#27671;&#28201;&#12398;&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12434;&#26684;&#32013;
PlotList[[1]] = grid.grabExpr({
  #&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#22522;&#26412;&#37096;&#20998;
  spiral_initialize_by_time(xlim = range(AnaData[, 1]),
                            unit_on_axis = "days",
                            period = "years",
                            period_per_loop = 10,
                            polar_lines_by = 360/10) #,
                            #vp_param = list(x = unit(0, "npc"), just = "left"))
  #&#12488;&#12521;&#12483;&#12463;&#12398;&#36861;&#21152;
  spiral_track(height = 0.8)
  #&#27671;&#28201;&#12398;&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;
  lt = spiral_horizon(AnaData[, 1], AnaData[, 2], use_bar = TRUE,
                      pos_fill = "#D73027", neg_fill = "#313695")
  #&#20961;&#20363;&#12398;&#35373;&#23450;
  #lgd = horizon_legend(lt, title = "MAX_Temperature")
  #&#20961;&#20363;&#12398;&#25551;&#20889;
  #ComplexHeatmap::draw(lgd, x = unit(1, "npc") + unit(2, "mm"), just = "left")
  #x&#36600;&#12398;&#36861;&#21152;
  spiral_axis(h = "top", curved_labels = TRUE, labels_gp = gpar(fontsize = 7))
  #&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12479;&#12452;&#12488;&#12523;
  grid.text("MAX_Temperature", x = 0, y = 1, just = c("left", "top"))
})

#&#26368;&#20302;&#27671;&#28201;&#12398;&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12434;&#26684;&#32013;
PlotList[[2]] = grid.grabExpr({
  #&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#22522;&#26412;&#37096;&#20998;
  spiral_initialize_by_time(xlim = range(AnaData[, 1]),
                            unit_on_axis = "days",
                            period = "years",
                            period_per_loop = 10,
                            polar_lines_by = 360/10) #,
                            #vp_param = list(x = unit(0, "npc"), just = "left"))
  #&#12488;&#12521;&#12483;&#12463;&#12398;&#36861;&#21152;
  spiral_track(height = 0.8)
  #&#27671;&#28201;&#12398;&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;
  lt = spiral_horizon(AnaData[, 1], AnaData[, 3], use_bar = TRUE,
                      pos_fill = "#D73027", neg_fill = "#313695")
  #&#20961;&#20363;&#12398;&#35373;&#23450;
  #lgd = horizon_legend(lt, title = "LOW_Temperature")
  #&#20961;&#20363;&#12398;&#25551;&#20889;
  #ComplexHeatmap::draw(lgd, x = unit(1, "npc") + unit(2, "mm"), just = "left")
  #x&#36600;&#12398;&#36861;&#21152;
  spiral_axis(h = "top", curved_labels = TRUE, labels_gp = gpar(fontsize = 7))
  #&#12473;&#12497;&#12452;&#12521;&#12523;&#12481;&#12515;&#12540;&#12488;&#12479;&#12452;&#12488;&#12523;
  grid.text("LOW_Temperature", x = 0, y = 1, just = c("left", "top"))
})

#cowplot&#12497;&#12483;&#12465;&#12540;&#12472;&#12391;&#12503;&#12525;&#12483;&#12488;
plot_grid(plotlist = PlotList, ncol = 2, nrow = 1)

出力例


少しでも、あなたの解析が楽になりますように!!

タイトルとURLをコピーしました