ggplot2の周辺ヒストグラムの散布図


137

以下のサンプルのように、周辺ヒストグラムを持つ散布図を作成する方法はありggplot2ますか?Matlabではそれがscatterhist()関数であり、Rと同等のものも存在します。ただし、ggplot2の場合は見ていません。

周辺ヒストグラムをもつ散布図

私は単一のグラフを作成することから始めましたが、それらを適切に配置する方法がわかりません。

 require(ggplot2)
 x<-rnorm(300)
 y<-rt(300,df=2)
 xy<-data.frame(x,y)
     xhist <- qplot(x, geom="histogram") + scale_x_continuous(limits=c(min(x),max(x))) + opts(axis.text.x = theme_blank(), axis.title.x=theme_blank(), axis.ticks = theme_blank(), aspect.ratio = 5/16, axis.text.y = theme_blank(), axis.title.y=theme_blank(), background.colour="white")
     yhist <- qplot(y, geom="histogram") + coord_flip() + opts(background.fill = "white", background.color ="black")

     yhist <- yhist + scale_x_continuous(limits=c(min(x),max(x))) + opts(axis.text.x = theme_blank(), axis.title.x=theme_blank(), axis.ticks = theme_blank(), aspect.ratio = 16/5, axis.text.y = theme_blank(), axis.title.y=theme_blank() )


     scatter <- qplot(x,y, data=xy)  + scale_x_continuous(limits=c(min(x),max(x))) + scale_y_continuous(limits=c(min(y),max(y)))
none <- qplot(x,y, data=xy) + geom_blank()

そして、ここに掲載されている機能でそれらを配置します。しかし、長い話を簡単に言うと、これらのグラフを作成する方法はありますか?


@DWin本当にありがとう-しかし、それは私の質問で私が出した解決策のほとんどです。ただし、geom_rag()は、以下のように非常に多くのことを考えるのが好きです!
セブ

1
同じトピックを取り上げた最近のブログ投稿から:blog.mckuhn.de/2009/09/learning-ggplot2-2d-plot-with.htmlも非常に見栄えが良い:)
Seb

グラフィックギャラリーの新しいWebサイトは次のとおり
enthusiasts.com– IRTFM

@Seb理にかなっていると思われる場合は、「受け入れられた回答」をggExtraパッケージに関するものに変更することを検討できます
DeanAttali

回答:


93

gridExtraパッケージには、ここに動作するはずです。まず、各ggplotオブジェクトを作成します。

hist_top <- ggplot()+geom_histogram(aes(rnorm(100)))
empty <- ggplot()+geom_point(aes(1,1), colour="white")+
         theme(axis.ticks=element_blank(), 
               panel.background=element_blank(), 
               axis.text.x=element_blank(), axis.text.y=element_blank(),           
               axis.title.x=element_blank(), axis.title.y=element_blank())

scatter <- ggplot()+geom_point(aes(rnorm(100), rnorm(100)))
hist_right <- ggplot()+geom_histogram(aes(rnorm(100)))+coord_flip()

次に、grid.arrange関数を使用します。

grid.arrange(hist_top, empty, scatter, hist_right, ncol=2, nrow=2, widths=c(4, 1), heights=c(1, 4))

プロット


6
1+は配置を示すためのものですが、内部の散布図を周辺のヒストグラムと「整列」させる場合は、ランダムサンプリングを再実行しないでください。
IRTFM 2011

1
あなたが正しい。ただし、それらは同じ分布からサンプリングされているため、周辺ヒストグラムは散布図と理論的に一致するはずです。
oeo4b 2011

8
「理論」では、それらは漸近的に「一致」します。実際には、それらが一致する回数はごくわずかです。提供されている例xy <- data.frame(x=rnorm(300), y=rt(300,df=2) )を使用data=xyして、ggplot呼び出しで使用するのは非常に簡単です。
IRTFM 2011

7
プロットの軸は通常正確に整列しないため、このソリューションはお勧めしません。うまくいけば、ggplot2の将来のバージョンでは、軸の位置合わせが簡単になり、プロットパネルの側面にカスタムの注釈を追加できるようになります(ラティスのカスタマイズされた2次軸関数のように)。
バティスト

9
いいえ、そうではありません。ggplot2は現在、軸ラベルの範囲などに応じて変化するさまざまなパネル幅を出力します。軸を位置合わせするために現在必要なハックの種類を確認するには、ggExtra :: align.plotsをご覧ください。
バプテスト

115

これは完全な応答ではありませんが、非常に簡単です。限界濃度を表示する別の方法と、透明度をサポートするグラフィック出力にアルファレベルを使用する方法も示します。

scatter <- qplot(x,y, data=xy)  + 
         scale_x_continuous(limits=c(min(x),max(x))) + 
         scale_y_continuous(limits=c(min(y),max(y))) + 
         geom_rug(col=rgb(.5,0,0,alpha=.2))
scatter

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


5
これは密度を示す興味深い方法です。この回答を追加していただきありがとうございます。:)
ミシェル

21
この方法は、周辺ヒストグラムを配置するよりもはるかに一般的であることに注意してください。実際、敷物プロットがあることは、私がマージナルヒストリグラムを使用して公開された記事を見たことがない、公開された記事で一般的です。
Xu Wang

非常に興味深く、直感的な代替回答!そして、とてもシンプル!正解以上の票を獲得するのも不思議ではありません。私の理解では、これは本質的に1次元のヒートマップであるということです。私の唯一の心配は、ヒートマップの解像度がヒストグラムほど高くないことです。例えば。プロットが小さい場合、すべてのラグが一緒に圧迫され、分布がわかりにくくなります。一方、ヒストグラムには制限がありません。アイデアをありがとう!
HongboZhu

94

これは少し遅れるかもしれませんが、少しggExtraのコードが含まれ、書くのが面倒な場合があるので、パッケージ()を作成することにしました。このパッケージは、タイトルがある場合やテキストが拡大された場合でも、プロットが互いにインラインになるようにするなど、いくつかの一般的な問題に対処しようとします。

基本的な考え方は、ここでの回答と似ていますが、それだけではありません。以下は、1000ポイントのランダムセットにマージナルヒストグラムを追加する方法の例です。うまくいけば、将来的にヒストグラム/密度プロットを簡単に追加できるようになります。

ggExtraパッケージへのリンク

library(ggplot2)
df <- data.frame(x = rnorm(1000, 50, 10), y = rnorm(1000, 50, 10))
p <- ggplot(df, aes(x, y)) + geom_point() + theme_classic()
ggExtra::ggMarginal(p, type = "histogram")

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


1
パッケージをどうもありがとう。そのまま使用できます!
heroxbd

このパッケージを使用して、色でグループ化されたオブジェクトの限界密度プロットを描画することは可能ですか?
GegznaV 2016年

いいえ、そのようなロジックはありません
DeanAttali 2016年

1
@jjrr何が機能しておらず、どのような問題が発生しているかはわかりませんが、githubでノートブックでのレンダリングに関する最近の問題があり、解決策もあります。これは便利ですgithub.com/daattali/ ggExtra / issues / 89
DeanAttali

1
@GegznaV、まだ限界密度プロットを色でグループ化する方法を探している場合、ggExtra 0.9で可能です:ggMarginal(p、type = "density"、size = 5、groupColour = TRUE)
MartineJ

46

さらに、私たちの後にこれを行う人々の検索時間を節約するために。

凡例、軸ラベル、軸テキスト、目盛りは、プロットを互いにずらしているため、プロットは見苦しく、一貫性がありません。

これらのテーマ設定のいくつかを使用してこれを修正できます。

+theme(legend.position = "none",          
       axis.title.x = element_blank(),
       axis.title.y = element_blank(),
       axis.text.x = element_blank(),
       axis.text.y = element_blank(), 
       plot.margin = unit(c(3,-5.5,4,3), "mm"))

スケールを調整し、

+scale_x_continuous(breaks = 0:6,
                    limits = c(0,6),
                    expand = c(.05,.05))

結果は正常に見えるでしょう:

例


3
参照これを整列プロットパネルに、より信頼性の高いソリューションのために
バティスト

はい。私の答えは古くなっています。提案されたソリューション@baptisteを使用してください。
Lorinc Nyitrai、2015年

@LorincNyitraiこのプロットを生成するためのコードを共有してください。また、2つのグループの周辺分布を使用してggplot2でPrecision-Recall散布図を作成したいのですが、2つのグループの周辺分布を実行できません。ありがとう
初心者

@初心者、この回答は3歳で、できるだけ古いものです。rdocumentation.org/packages/gtable/versions/0.2.0/topics/gtableなどを使用します。
Lorinc Nyitrai 2017年

29

分布の限界指標の一般的な精神における、BondedDustの回答のごくわずかなバリエーション。

Edward Tufteは、ラグプロットのこの使用を「一点鎖線プロット」と呼び、VDQIで軸線を使用して各変数の範囲を示す例があります。私の例では、軸ラベルとグリッド線もデータの分布を示しています。ラベルは、Tukeyの5つの数値サマリー(最小、下ヒンジ、中央値、上ヒンジ、最大)の値に配置されており、各変数の広がりをすばやく確認できます。

したがって、これらの5つの数値は箱ひげ図の数値表現です。グリッド線が不等間隔に配置されていることから、軸のスケールが非線形(この例では線形)であることが示唆されるため、少し注意が必要です。グリッド線を省略したり、通常の場所に配置したりして、ラベルに5つの数値の要約を表示させるのが最善の方法です。

x<-rnorm(300)
y<-rt(300,df=10)
xy<-data.frame(x,y)

require(ggplot2); require(grid)
# make the basic plot object
ggplot(xy, aes(x, y)) +        
  # set the locations of the x-axis labels as Tukey's five numbers   
  scale_x_continuous(limit=c(min(x), max(x)), 
                     breaks=round(fivenum(x),1)) +     
  # ditto for y-axis labels 
  scale_y_continuous(limit=c(min(y), max(y)),
                     breaks=round(fivenum(y),1)) +     
  # specify points
  geom_point() +
  # specify that we want the rug plot
  geom_rug(size=0.1) +   
  # improve the data/ink ratio
  theme_set(theme_minimal(base_size = 18))

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


12

異なるグループを比較する場合、この種のプロットには満足のいく解決策がなかったため、これを行う関数を作成しました。

グループ化されたデータとグループ化されていないデータの両方で機能し、追加のグラフィックパラメータを受け入れます。

marginal_plot(x = iris$Sepal.Width, y = iris$Sepal.Length)

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

marginal_plot(x = Sepal.Width, y = Sepal.Length, group = Species, data = iris, bw = "nrd", lm_formula = NULL, xlab = "Sepal width", ylab = "Sepal length", pch = 15, cex = 0.5)

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


9

ggpubrこの問題に非常にうまく機能しているように見えるパッケージ()を見つけました。データを表示するいくつかの可能性を考慮しています。

パッケージへのリンクはここにあり、このリンクには、それを使用するための素晴らしいチュートリアルがあります。完全を期すために、再現した例の1つを添付します。

最初にパッケージをインストールしました(が必要ですdevtools

if(!require(devtools)) install.packages("devtools")
devtools::install_github("kassambara/ggpubr")

グループごとに異なるヒストグラムを表示する特定例えば、との関係に言及しggExtra、「の1つの制限はggExtra、それが散布図及び限界のプロットで複数のグループに対応できないということである以下のRコードでは、我々はAを提供します。cowplotパッケージを使用したソリューション。」私の場合、後者のパッケージをインストールする必要がありました。

install.packages("cowplot")

そして、私はこのコードの一部に従いました:

# Scatter plot colored by groups ("Species")
sp <- ggscatter(iris, x = "Sepal.Length", y = "Sepal.Width",
            color = "Species", palette = "jco",
            size = 3, alpha = 0.6)+
border()                                         
# Marginal density plot of x (top panel) and y (right panel)
xplot <- ggdensity(iris, "Sepal.Length", fill = "Species",
               palette = "jco")
yplot <- ggdensity(iris, "Sepal.Width", fill = "Species", 
               palette = "jco")+
rotate()
# Cleaning the plots
sp <- sp + rremove("legend")
yplot <- yplot + clean_theme() + rremove("legend") 
xplot <- xplot + clean_theme() + rremove("legend")
# Arranging the plot using cowplot
library(cowplot)
plot_grid(xplot, NULL, sp, yplot, ncol = 2, align = "hv", 
      rel_widths = c(2, 1), rel_heights = c(1, 2))

私にとってはうまくいきました:

アイリスが周辺ヒストグラム散布図を設定

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


中央のプロットを正方形にするために何をする必要がありますか?
JAQuent

ドットの形って?に引数shape = 19を 追加してみてくださいggscatter。形状のコードはこちら
Alf Pascu

7

ggstatsplotを使用すると、周辺ヒストグラムを使用して魅力的な散布図を簡単に作成できます(モデルに適合して説明することもできます)。

data(iris)

library(ggstatsplot)

ggscatterstats(
  data = iris,                                          
  x = Sepal.Length,                                                  
  y = Sepal.Width,
  xlab = "Sepal Length",
  ylab = "Sepal Width",
  marginal = TRUE,
  marginal.type = "histogram",
  centrality.para = "mean",
  margins = "both",
  title = "Relationship between Sepal Length and Sepal Width",
  messages = FALSE
)

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

または少し魅力的な(デフォルトで)ggpubr

devtools::install_github("kassambara/ggpubr")
library(ggpubr)

ggscatterhist(
  iris, x = "Sepal.Length", y = "Sepal.Width",
  color = "Species", # comment out this and last line to remove the split by species
  margin.plot = "histogram", # I'd suggest removing this line to get density plots
  margin.params = list(fill = "Species", color = "black", size = 0.2)
)

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

更新:

@aickleyによって提案されたように、私は開発バージョンを使用してプロットを作成しました。


1
y軸のヒストグラムはx軸のヒストグラムの単なるコピーであるため、正しくありません。この問題は最近修正されましたgithub.com/kassambara/ggpubr/issues/85
aickley

7

これは古い質問ですが、最近同じ問題に遭遇したので、ここに更新を投稿すると便利だと思いました(助けてくれたStefanie Muellerに感謝します!)。

gridExtraを使用した最も賛成の回答は機能しますが、コメントで指摘されているように、軸の整列は困難/ハックです。これは、ggExtraパッケージのコマンドggMarginalを使用して解決できるようになりました。

#load packages
library(tidyverse) #for creating dummy dataset only
library(ggExtra)

#create dummy data
a = round(rnorm(1000,mean=10,sd=6),digits=0)
b = runif(1000,min=1.0,max=1.6)*a
b = b+runif(1000,min=9,max=15)

DummyData <- data.frame(var1 = b, var2 = a) %>% 
  filter(var1 > 0 & var2 > 0)

#plot
p = ggplot(DummyData, aes(var1, var2)) + geom_point(alpha=0.3)
ggMarginal(p, type = "histogram")

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


これは、元のggExtraパッケージ開発者が別の回答で投稿したことを認識しました。上記で説明した理由により、代わりに受け入れられた回答を作成することをお勧めします。
Victoria Auyeung

6

私はそれらのオプションを試しましたが、結果またはそこに到達するために使用する必要がある厄介なコードには満足できませんでした。ラッキー私、トーマス・林ペダーセンはちょうどと呼ばれるパッケージ開発のパッチワークかなりエレガントなやり方で仕事を取得し、。

周辺ヒストグラムを持つ散布図を作成する場合は、最初にこれら3つのプロットを別々に作成する必要があります。

library(ggplot2)

x <- rnorm(300)
y <- rt(300, df = 2)
xy <- data.frame(x, y)

plot1 <- ggplot(xy, aes(x = x, y = y)) + 
  geom_point() 

dens1 <- ggplot(xy, aes(x = x)) + 
  geom_histogram(color = "black", fill = "white") + 
  theme_void()

dens2 <- ggplot(xy, aes(x = y)) + 
  geom_histogram(color = "black", fill = "white") + 
  theme_void() + 
  coord_flip()

あとは、これらのプロットを単純なものとして追加+し、関数でレイアウトを指定するだけplot_layout()です。

library(patchwork)

dens1 + plot_spacer() + plot1 + dens2 + 
  plot_layout(
    ncol = 2, 
    nrow = 2, 
    widths = c(4, 1),
    heights = c(1, 4)
  ) 

この関数plot_spacer()は、右上隅に空のプロットを追加します。他のすべての議論は自明です。

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

ヒストグラムは選択したビン幅に大きく依存するため、密度プロットを好むと主張する人もいます。いくつかの小さな変更を加えると、たとえばアイトラッキングデータの場合、美しいプロットが得られます。

library(ggpubr)

plot1 <- ggplot(df, aes(x = Density, y = Face_sum, color = Group)) + 
  geom_point(aes(color = Group), size = 3) + 
  geom_point(shape = 1, color = "black", size = 3) + 
  stat_smooth(method = "lm", fullrange = TRUE) +
  geom_rug() + 
  scale_y_continuous(name = "Number of fixated faces", 
                     limits = c(0, 205), expand = c(0, 0)) + 
  scale_x_continuous(name = "Population density (lg10)", 
                     limits = c(1, 4), expand = c(0, 0)) + 
  theme_pubr() +
  theme(legend.position = c(0.15, 0.9)) 

dens1 <- ggplot(df, aes(x = Density, fill = Group)) + 
  geom_density(alpha = 0.4) + 
  theme_void() + 
  theme(legend.position = "none")

dens2 <- ggplot(df, aes(x = Face_sum, fill = Group)) + 
  geom_density(alpha = 0.4) + 
  theme_void() + 
  theme(legend.position = "none") + 
  coord_flip()

dens1 + plot_spacer() + plot1 + dens2 + 
  plot_layout(ncol = 2, nrow = 2, widths = c(4, 1), heights = c(1, 4))

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

この時点ではデータは提供されていませんが、基本的な原則は明確である必要があります。


4

@ alf-pascuによる回答に基づいて、各プロットを手動で設定し、それらを配置することでcowplot、メインプロットとマージナルプロット(他のソリューションのいくつかと比較して)の両方に関して多くの柔軟性が得られます。グループによる分布はその一例です。メインプロットを2D密度プロットに変更することもできます。

以下は、(適切に整列された)周辺ヒストグラムをもつ散布図を作成します。

library("ggplot2")
library("cowplot")

# Set up scatterplot
scatterplot <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
  geom_point(size = 3, alpha = 0.6) +
  guides(color = FALSE) +
  theme(plot.margin = margin())


# Define marginal histogram
marginal_distribution <- function(x, var, group) {
  ggplot(x, aes_string(x = var, fill = group)) +
    geom_histogram(bins = 30, alpha = 0.4, position = "identity") +
    # geom_density(alpha = 0.4, size = 0.1) +
    guides(fill = FALSE) +
    theme_void() +
    theme(plot.margin = margin())
}

# Set up marginal histograms
x_hist <- marginal_distribution(iris, "Sepal.Length", "Species")
y_hist <- marginal_distribution(iris, "Sepal.Width", "Species") +
  coord_flip()

# Align histograms with scatterplot
aligned_x_hist <- align_plots(x_hist, scatterplot, align = "v")[[1]]
aligned_y_hist <- align_plots(y_hist, scatterplot, align = "h")[[1]]

# Arrange plots
plot_grid(
  aligned_x_hist
  , NULL
  , scatterplot
  , aligned_y_hist
  , ncol = 2
  , nrow = 2
  , rel_heights = c(0.2, 1)
  , rel_widths = c(1, 0.2)
)

周辺ヒストグラムをもつ散布図

代わりに2D密度プロットをプロットするには、メインプロットを変更するだけです。

# Set up 2D-density plot
contour_plot <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
  stat_density_2d(aes(alpha = ..piece..)) +
  guides(color = FALSE, alpha = FALSE) +
  theme(plot.margin = margin())

# Arrange plots
plot_grid(
  aligned_x_hist
  , NULL
  , contour_plot
  , aligned_y_hist
  , ncol = 2
  , nrow = 2
  , rel_heights = c(0.2, 1)
  , rel_widths = c(1, 0.2)
)

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


3

ggpubrおよびを使用する別のソリューションですcowplotが、ここではを使用してプロットを作成し、次のコマンドを使用cowplot::axis_canvasして元のプロットに追加しますcowplot::insert_xaxis_grob

library(cowplot) 
library(ggpubr)

# Create main plot
plot_main <- ggplot(faithful, aes(eruptions, waiting)) +
  geom_point()

# Create marginal plots
# Use geom_density/histogram for whatever you plotted on x/y axis 
plot_x <- axis_canvas(plot_main, axis = "x") +
  geom_density(aes(eruptions), faithful)
plot_y <- axis_canvas(plot_main, axis = "y", coord_flip = TRUE) +
  geom_density(aes(waiting), faithful) +
  coord_flip()

# Combine all plots into one
plot_final <- insert_xaxis_grob(plot_main, plot_x, position = "top")
plot_final <- insert_yaxis_grob(plot_final, plot_y, position = "right")
ggdraw(plot_final)

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


2

現在、散布図とその周辺ヒストグラムを作成するCRANパッケージが少なくとも1つあります。

library(psych)
scatterHist(rnorm(1000), runif(1000))

scatterHistからのサンプルプロット


0

のインタラクティブなフォームを使用して、ggExtra::ggMarginalGadget(yourplot) ボックスプロット、バイオリンプロット、密度プロット、ヒストグラムを簡単に選択できます。

そのように

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.