1つのプロットで多くの変数を視覚化する


25

特定の変数(〜15)の値が時間とともにどのように変化するかを示したいのですが、変数が各年でどのように異なるかを示したいと思います。だから私はこのプロットを作成しました:

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

しかし、配色を変更したり、さまざまな線/形状タイプを追加したりしても、これは面倒に見えます。この種のデータを視覚化するより良い方法はありますか?

Rコードを使用したテストデータ:

structure(list(Var = structure(c(1L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 
6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 
8L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 11L, 11L, 11L, 11L, 11L, 
11L, 11L, 12L, 12L, 12L, 12L, 12L, 12L, 13L, 14L, 14L, 14L, 14L, 
14L, 14L, 14L, 16L, 16L, 16L, 16L, 16L, 16L, 17L, 17L, 17L, 17L, 
17L, 17L, 17L, 18L, 18L, 18L, 18L, 18L, 18L, 18L), .Label = c("A", 
"B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", 
"O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"), class = "factor"), 
    Year = c(2015L, 1991L, 1993L, 1996L, 2000L, 2004L, 2011L, 
    2015L, 1991L, 1993L, 1996L, 2000L, 2004L, 2011L, 2015L, 1991L, 
    1993L, 1996L, 2000L, 2004L, 2011L, 2015L, 1993L, 1996L, 2000L, 
    2004L, 2011L, 2015L, 1991L, 1993L, 1996L, 2000L, 2004L, 2011L, 
    2015L, 1991L, 1993L, 1996L, 2000L, 2004L, 2011L, 2015L, 1991L, 
    1993L, 1996L, 2000L, 2004L, 2011L, 2015L, 1991L, 1993L, 1996L, 
    2000L, 2004L, 2011L, 2015L, 1993L, 1996L, 2000L, 2004L, 2011L, 
    2015L, 2015L, 1991L, 1993L, 1996L, 2000L, 2004L, 2011L, 2015L, 
    1991L, 1993L, 1996L, 2000L, 2011L, 2015L, 1991L, 1993L, 1996L, 
    2000L, 2004L, 2011L, 2015L, 1991L, 1993L, 1996L, 2000L, 2004L, 
    2011L, 2015L), Val = c(25.6, 22.93, 20.82, 24.1, 24.5, 29, 
    25.55, 24.5, 24.52, 20.73, 25.8, 25.5, 29.5, 27.7, 25.1, 
    25, 24.55, 26.75, 25, 30.5, 27.25, 25.1, 22.4, 27.07, 26, 
    29, 27.2, 24.2, 23, 24.27, 27.68, 27, 30.5, 28.1, 24.9, 23.75, 
    22.75, 27.25, 25, 29, 28.45, 24, 20.25, 17.07, 24.45, 25, 
    28.5, 26.75, 24.9, 21.25, 20.65, 25.1, 24.5, 26.5, 25.35, 
    23.5, 21.93, 26.5, 24.5, 29, 29.1, 26.4, 28.1, 23.75, 26.5, 
    28.05, 27, 30.5, 25.65, 23.3, 23.25, 24.57, 26.07, 27.5, 
    28.85, 27.7, 22, 23.43, 26.88, 27, 30.5, 29.25, 28.1, 23, 
    23.8, 28.32, 27, 29.5, 29.15, 27.6)), row.names = c(1L, 4L, 
5L, 6L, 7L, 8L, 9L, 10L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 
21L, 22L, 23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 31L, 32L, 35L, 
36L, 37L, 38L, 39L, 40L, 41L, 44L, 45L, 46L, 47L, 48L, 49L, 50L, 
53L, 54L, 55L, 56L, 57L, 58L, 59L, 62L, 63L, 64L, 65L, 66L, 67L, 
68L, 69L, 70L, 71L, 72L, 73L, 74L, 75L, 78L, 79L, 80L, 81L, 82L, 
83L, 84L, 87L, 88L, 89L, 90L, 91L, 92L, 95L, 96L, 97L, 98L, 99L, 
100L, 101L, 104L, 105L, 106L, 107L, 108L, 109L, 110L), na.action = structure(c(2L, 
3L, 11L, 12L, 33L, 34L, 42L, 43L, 51L, 52L, 60L, 61L, 76L, 77L, 
85L, 86L, 93L, 94L, 102L, 103L), .Names = c("2", "3", "11", "12", 
"33", "34", "42", "43", "51", "52", "60", "61", "76", "77", "85", 
"86", "93", "94", "102", "103"), class = "omit"), class = "data.frame", .Names = c("Var", 
"Year", "Val"))

2
データを投稿できますか?ほぼ同じような例を見つけるのは簡単ですが、スレッドを結び付けるには、同じサンドボックスを使って遊ぶのが役立ちます。また、グリーンゾーンの重要性は何ですか?
ニックコックス


@NickCox確かに、もっと早く考えたことがあるはずです!必須ではないため、グリーンゾーンを

回答:


42

偶然かどうかにかかわらず、あなたの例は最初に最適なサイズ(15グループごとに最大7つの値)であり、問​​題があることをグラフィカルに示します。もう1つは、他の非常に単純なソリューションを許可することです。グラフは、さまざまな分野の人々によってしばしばスパゲッティと呼ばれる種類のものですが、その用語が愛情的であるか虐待的であるかどうかは必ずしも明確ではありません。グラフは、すべてのグループの集合的または家族の行動を示していますが、調査する詳細を示すことはまったく望みがありません。

1つの標準的な代替方法は、個別のパネルに個別のグループを表示することですが、そのため、グループ間の正確な比較が困難になる可能性があります。各グループは、他のグループのコンテキストから分離されています。

では、両方のアイデアを組み合わせてみてください。グループごとに個別のパネルを作成し、他のグループも背景として表示します。これは、焦点が合っているグループを強調表示し、他のグループを軽視することに決定的に依存します。この例では、線の色や太さなどを使用すると簡単です。

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

この場合、考えられる実用的または科学的な重要性または関心の詳細が強調表示されます。

  1. AとMの値は1つだけです。

  2. 他のすべてのケースでは、指定されたすべての年のすべての値がありません。

  3. 一部のグループは高いプロット、低いグループなどをプロットします。

ここでは解釈を試みません。データは匿名ですが、それはいずれにしても研究者の関心事です。

ソフトウェアで簡単または可能なものに応じて、軸のラベルとタイトルが繰り返されるかどうかなど、小さな詳細を変更する範囲があります(賛否両論の単純な引数があります)。

大きな問題は、この戦略がより一般的に機能する範囲です。グループの数が主要なドライバーであり、各グループのポイント数よりも重要です。大まかに言えば、このアプローチは最大約25グループ(5 x 5ディスプレイなど)で動作します:グループが増えると、グラフが小さくなり読みにくくなるだけでなく、研究者でさえすべてのスキャンを行う傾向がなくなりますパネル。数百(数千など)のグループがある場合、通常は少数のグループを選択して表示することが不可欠です。いくつかの「典型的な」パネルといくつかの「極端な」パネルを選択するなど、いくつかの基準の組み合わせが必要になります。これは、プロジェクトの目標と、各データセットにとって何が理にかなっているかについてのいくつかのアイデアによって推進されるべきです。効率的な別のアプローチは、各パネルで少数のシリーズを強調することです。そう、広いグループが25個ある場合、それぞれの広いグループを他のすべてのグループとともに背景として表示できます。あるいは、平均化やその他の要約が行われる場合があります。(たとえば)主要なコンポーネントまたは独立したコンポーネントを使用することも良い考えです。

この例ではラインプロットが必要ですが、原則は当然非常に一般的です。例は、乗算プロット、散布図、モデル診断プロットなどです。

このアプローチの参考文献[他の人は大歓迎です]:

Cox、NJ2010。サブセットのグラフ化。Stata Journal 10:670-681。

Knaflic、CN2015。データを使用したスト​​ーリーテリング:ビジネスプロフェッショナル向けのデータ視覚化ガイド。ニュージャージー州ホーボーケン:ワイリー。

Koenker、R。2005。分位点回帰。ケンブリッジ:ケンブリッジ大学出版局。12-13ページを参照してください。

Schwabish、JA2014。データを視覚化するエコノミストのガイド。Journal of Economic Perspectives 28:209-234。

Unwin、A。2015。R.Boca Raton によるグラフィカルデータ分析、FL:CRC Press。

Wallgren、A.、B。Wallgren、R。Persson、U。Jorner、およびJ.-A. ハアランド。1996. 統計とデータのグラフ化:より良いグラフの作成。ニューベリーパーク、CA:セージ。

注:グラフはStataで作成されました。subsetplotまずでインストールする必要がありますssc inst subsetplot。Rからデータをコピーして貼り付け、値ラベルを定義して、年をとして表示し90 95 00 05 10 15ます。主なコマンドは

subsetplot connected Val Year, by(Var) c(L) lcolor(gs12) backdrop(line) xtitle("") combine(imargin(small)) subset(lcolor(blue) mcolor(blue))

編集追加参照2016年5月、9月、12月。2017年4月、6月、2018年12月、2019年4月:

カイロ、2016年 。真実の芸術:コミュニケーションのためのデータ、チャート、地図。 カリフォルニア州サンフランシスコ:新しいライダー。p.211

Camões、J.2016。職場でのデータ:Microsoft Excelで効果的なグラフと情報グラフィックを作成するためのベストプラクティス。カリフォルニア州サンフランシスコ:新しいライダー。p.354

Carr、DBおよびPickle、LW2010。マイクロマップによるデータパターンの視覚化。ボカラトン、フロリダ州:CRCプレス。p.85。

Grant、R.2019。データの視覚化:チャート、マップ、およびインタラクティブグラフィック。 ボカラトン、フロリダ州:CRCプレス。p.52。

Koponen、J.およびHildén、J. 2019. The Data Visualization Handbook。 エスポー:Aalto ARTS Books。p.101を参照してください。

Kriebel、A。、およびMurray、E。2018#MakeoverMonday:データを視覚化および分析する方法の改善、一度に1つのグラフ。ニュージャージー州ホーボーケン:ジョン・ワイリー。p.303。

Rougier、NP、Droettboom、M。およびBourne、PE2014。より良い数字のための10の簡単なルール。 PLOS計算生物学 10(9):e1003833。doi:10.1371 / journal.pcbi.1003833 リンクはこちら

Schwabish、J. 2017年 より良いプレゼンテーション:学者、研究者、およびWonksためのAガイド。 ニューヨーク:コロンビア大学出版局。p.98をご覧ください。

ウィッカム、H。2016。ggplot2:データ分析用のエレガントなグラフィック。チャム:スプリンガー。p.157を参照してください。


+1、素晴らしい、このタイプのチャートを実行できるRまたはSAS機能はありますか?本当に素晴らしいです。
予報官

私はこのアイデアが本当に好きです!ggplot2を使用してRでこれをプロットする最良の方法を考えてみてください。私は答えを受け入れる前に少し待って、それでいいことを願っています。

2
申し訳ありませんが、SASで何かを行う方法がわかりません。確かStataのは、何かできることは、Rは、同様またはより良い行うことができ、またはそのユーザーが....私に言っておくので
ニック・コックス

@NickCoxまったく問題ありません、私はそれを理解しました、それは本当に良く見え、私の目的に最適です。

@NickCox、さらに2つの参照が1あるWSクリーブランドによってデータのグラフ化ザ要素を .A新しい本、2 データとストーリーテリング:コールNussbaumer Knaflicにより、ビジネスプロフェッショナルのためのAデータの可視化ガイド .Thisブック(#2)は、ケーススタディを持っています「スパゲッティグラフを回避するための戦略」と呼ばれる章。
予報官

22

ニックの答えを補完するものとして、シミュレートされたデータを使用して同様のプロットを作成するためのいくつかのRコードがあります。

library(ggplot2)

get_df <- function(label="group A", n_obs=10, drift=runif(1)) {
    df <- data.frame(time=seq(1, n_obs), label=label)
    df$y <- df$time * drift + cumsum(rnorm(n_obs))
    return(df)
}
df_list <- lapply(sprintf("group %s", toupper(letters[1:9])),
                  function(label) { get_df(label) })
df <- do.call(rbind, df_list)
df$label2 <- df$label

p <- (ggplot(df, aes(x=time, y=y, group=label2)) +
      geom_line(size=0.9, alpha=0.8,
                data=df[, c("time", "y", "label2")], color="grey") +
      geom_line(size=1.1, color="black") +
      ylab("") +
      theme_bw() +
      theme(panel.border=element_blank()) +
      theme(strip.background=element_blank()) +
      facet_wrap(~ label))
p
ggsave("example_facet.png", p, width=10, height=8)

プロット例


6

ggplot2Rでアプローチを使用したいfacetshade場合は、パッケージ内の関数を検討してくださいextracat。これは、ラインプロットだけでなく、一般的なアプローチを提供します。散布図の例を次に示します(このページの下部から)。

data(olives, package="extracat")
library(scales)
fs1 <- facetshade(data = olives,
                  aes(x = palmitic, y = palmitoleic), f = .~Area)
fs1 + geom_point(colour = alpha("black", 0.05)) +
      geom_point(data = olives, colour = "red") +
      facet_wrap(f=~Area, nrow=3) + theme(legend.position="none")

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


編集:エイドリアンの以前の答えからシミュレートされたデータセットを使用して:

library(extracat)
facetshade(df, aes(x=time, y=y), f = .~label, bg.all = FALSE, keep.orig = TRUE) +
           geom_line(aes(x=time, y=y, group=orig.label),colour = alpha(1,0.3)) +
           geom_line(data=df, aes(colour=label), size = 1.2) + xlab("") + ylab("")

別のアプローチは、背景用と強調表示されたケース用の2つの別々のレイヤーを描画することです。ファセット変数なしでデータセットを使用して背景レイヤーを描画するのがコツです。オリーブオイルデータセットのコードは次のとおりです。

data(olives, package="extracat")
ggplot(olives, aes(palmitic, palmitoleic)) + 
  facet_wrap(~Area, nrow=3) + 
  geom_point(data=olives %>% select(-Area), colour=alpha("black", 0.05)) + 
  geom_point(data=olives, colour="red") + 
  theme(legend.position="none")

1
これは素晴らしい一般的なアプローチ(+1)のように見えますが、特定の例は別の問題に関連しています。強調表示された領域が異なる繰り返しの散布図は、時系列に関する質問にはうまくいきません。
セクストゥスエンピリカス

@martin実際、それはエイドリアンのソリューションでもあります。彼は2つの同一のラベリング変数を使用して、1つを背景レイヤーにドロップできることに注意してください。コーディングのアイデアは、以下の整頓された表記法でより明確になり、グラフィックスのエレガントなフォーマット設定はコードの重要な部分を隠すことがあります。 ggplot(df %>% select(-label), aes(x=time, y=y, group=label2)) + geom_line(alpha=0.8, color="grey") + labs(y=NULL) + geom_line(data=df, color="red") + facet_wrap(~ label)
アントニーアンウィン

5

Ch。に触発されたソリューションを次に示します。11.3、ハドリー・ウィッカムのggplot2の本の「テキサス住宅データ」のセクション。ここでは、各時系列に線形モデルを適合させ、残差(平均0を中心とする)を取得し、異なる色で要約線を描画します。

library(ggplot2)
library(dplyr)
#works with dplyr version 0.4.3.9000 from Github (hadley/dplyr@4f2d7f8), or higher

df1 <- as.data.frame(list(Var = structure(c(1L, 2L, 2L, 2L, 2L, 2L, 2L, 
                                 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 
                                 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 
                                 8L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 11L, 11L, 11L, 11L, 11L, 
                                 11L, 11L, 12L, 12L, 12L, 12L, 12L, 12L, 13L, 14L, 14L, 14L, 14L, 
                                 14L, 14L, 14L, 16L, 16L, 16L, 16L, 16L, 16L, 17L, 17L, 17L, 17L, 
                                 17L, 17L, 17L, 18L, 18L, 18L, 18L, 18L, 18L, 18L), .Label = c("A", 
                                                                                               "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", 
                                                                                               "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"), class = "factor"), 
               Year = c(2015L, 1991L, 1993L, 1996L, 2000L, 2004L, 2011L, 
                        2015L, 1991L, 1993L, 1996L, 2000L, 2004L, 2011L, 2015L, 1991L, 
                        1993L, 1996L, 2000L, 2004L, 2011L, 2015L, 1993L, 1996L, 2000L, 
                        2004L, 2011L, 2015L, 1991L, 1993L, 1996L, 2000L, 2004L, 2011L, 
                        2015L, 1991L, 1993L, 1996L, 2000L, 2004L, 2011L, 2015L, 1991L, 
                        1993L, 1996L, 2000L, 2004L, 2011L, 2015L, 1991L, 1993L, 1996L, 
                        2000L, 2004L, 2011L, 2015L, 1993L, 1996L, 2000L, 2004L, 2011L, 
                        2015L, 2015L, 1991L, 1993L, 1996L, 2000L, 2004L, 2011L, 2015L, 
                        1991L, 1993L, 1996L, 2000L, 2011L, 2015L, 1991L, 1993L, 1996L, 
                        2000L, 2004L, 2011L, 2015L, 1991L, 1993L, 1996L, 2000L, 2004L, 
                        2011L, 2015L), 
               Val = c(25.6, 22.93, 20.82, 24.1, 24.5, 29, 
                       25.55, 24.5, 24.52, 20.73, 25.8, 25.5, 29.5, 27.7, 25.1, 
                       25, 24.55, 26.75, 25, 30.5, 27.25, 25.1, 22.4, 27.07, 26, 
                       29, 27.2, 24.2, 23, 24.27, 27.68, 27, 30.5, 28.1, 24.9, 23.75, 
                       22.75, 27.25, 25, 29, 28.45, 24, 20.25, 17.07, 24.45, 25, 
                       28.5, 26.75, 24.9, 21.25, 20.65, 25.1, 24.5, 26.5, 25.35, 
                       23.5, 21.93, 26.5, 24.5, 29, 29.1, 26.4, 28.1, 23.75, 26.5, 
                       28.05, 27, 30.5, 25.65, 23.3, 23.25, 24.57, 26.07, 27.5, 
                       28.85, 27.7, 22, 23.43, 26.88, 27, 30.5, 29.25, 28.1, 23, 
                       23.8, 28.32, 27, 29.5, 29.15, 27.6)), 
               row.names = c(1L, 4L, 
                           5L, 6L, 7L, 8L, 9L, 10L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 
                           21L, 22L, 23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 31L, 32L, 35L, 
                           36L, 37L, 38L, 39L, 40L, 41L, 44L, 45L, 46L, 47L, 48L, 49L, 50L, 
                           53L, 54L, 55L, 56L, 57L, 58L, 59L, 62L, 63L, 64L, 65L, 66L, 67L, 
                           68L, 69L, 70L, 71L, 72L, 73L, 74L, 75L, 78L, 79L, 80L, 81L, 82L, 
                           83L, 84L, 87L, 88L, 89L, 90L, 91L, 92L, 95L, 96L, 97L, 98L, 99L, 
                           100L, 101L, 104L, 105L, 106L, 107L, 108L, 109L, 110L), 
               na.action = structure(c(2L, 
                          3L, 11L, 12L, 33L, 34L, 42L, 43L, 51L, 52L, 60L, 61L, 76L, 77L, 
                          85L, 86L, 93L, 94L, 102L, 103L), 
                .Names = c("2", "3", "11", "12","33", "34", "42", "43", "51", "52", "60", 
                           "61", "76", "77", "85", "86", "93", "94", "102", "103"), class = "omit"), 
                class = "data.frame", .Names = c("Var","Year", "Val"))


df1 %>%
        group_by(Var) %>%
        do(mutate(.,resid = resid(lm(Val ~ Year, data=., na.action = na.exclude)))) %>%
        ggplot(aes(Year, resid)) +
        labs(y=paste0("Val "), x="Year") +
        geom_line(aes(group = Var), alpha = 1/5) +
        geom_line(stat = "summary", fun.y = "mean", colour = "red")

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


1
ここでの主なアイデアは、目と心を助けるために何らかの種類の要約曲線を追加できるということです。同意しましたが、あなたの答えでは、元の単位と値を残すのではなく、平均(または参照レベル)0にシフトすることのトレードオフを綴ることができました。主題の専門家および/またはクライアントは、24または28または他の値の観点から考えるかもしれません。当然、ここのデータは議論の手段にすぎませんが、ポイントは非常に一般的です。
ニックコックス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.