Streudiagramm mit marginalen Histogrammen in ggplot2

Gibt es eine Möglichkeit, Streudiagramme mit marginalen Histogrammen zu erstellen, genau wie im Beispiel in ggplot2 ? In Matlab ist es die scatterhist() function und es gibt auch Äquivalente für R. Allerdings habe ich es nicht für ggplot2 gesehen.

Streudiagramm mit marginalen Histogrammen

Ich habe einen Versuch gestartet, indem ich die einzelnen Graphen erstellt habe, aber nicht weiß, wie man sie richtig anordnet.

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

und arrangiere sie mit der hier eingestellten function. Aber um es kurz zu machen: Gibt es eine Möglichkeit, diese Graphen zu erstellen?

   

    Das gridExtra Paket sollte hier funktionieren. Beginne damit, jedes der ggplot-Objekte zu erstellen:

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

    Dann benutze die function grid.arrange:

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

    Handlung

    Dies ist keine vollständig antwortende Antwort, aber es ist sehr einfach. Es veranschaulicht eine alternative Methode zum Anzeigen von Randdichten und auch die Verwendung von Alpha-Ebenen für grafische Darstellung, die Transparenz unterstützt:

     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 

    Bildbeschreibung hier eingeben

    Das könnte etwas spät sein, aber ich habe beschlossen, dafür ein Paket ( ggExtra ) zu ggExtra da es ein wenig Code ggExtra und mühsam geschrieben werden kann. Das Paket versucht auch, ein allgemeines Problem zu lösen, z. B. um sicherzustellen, dass selbst bei einem Titel oder bei Vergrößerung des Textes die Plots immer noch miteinander verknüpft sind.

    Die Grundidee ist ähnlich wie die Antworten hier, aber es geht ein bisschen darüber hinaus. Hier ist ein Beispiel, wie Randhistogramme zu einer zufälligen Menge von 1000 Punkten hinzugefügt werden. Hoffentlich erleichtert dies das Hinzufügen von Histogrammen / Dichtekurven in der Zukunft.

    Link zum ggExtra-Paket

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

    Bildbeschreibung hier eingeben

    Eine Ergänzung, nur um ein wenig Suchzeit für Leute zu sparen, die das nach uns tun.

    Legenden, Achsenbeschriftungen, Achstexte, Ticks lassen die Plots voneinander abweichen, so dass Ihre Handlung hässlich und inkonsistent aussehen wird.

    Sie können dies korrigieren, indem Sie einige dieser Designeinstellungen verwenden,

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

    und richten Sie Skalen aus,

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

    Die Ergebnisse werden also gut aussehen:

    ein Beispiel

    Nur eine sehr kleine Variation der Antwort von BondedDust , im allgemeinen Geist der marginalen Verteilungsindikatoren.

    Edward Tufte hat diese Verwendung von Rug-Plots als “Punkt-Strich-Plot” bezeichnet und hat in VDQI ein Beispiel, die Achsenlinien zu verwenden, um den Bereich jeder Variablen anzugeben. In meinem Beispiel zeigen die Achsenbeschriftungen und Gitterlinien auch die Verteilung der Daten an. Die Beschriftungen befinden sich bei den Werten der fünf Zahlenzusammenfassung von Tukey (Minimum, Unteres Scharnier, Median, Oberes Scharnier, Maximum) und geben einen schnellen Eindruck von der Verteilung der einzelnen Variablen.

    Diese fünf Zahlen sind somit eine numerische Darstellung eines Boxplots. Es ist ein bisschen schwierig, weil die Gitterlinien mit ungleichem Abstand vorschlagen, dass die Achsen eine nichtlineare Skala haben (in diesem Beispiel sind sie linear). Vielleicht wäre es am besten, Rasterlinien wegzulassen oder sie an den regulären Orten zu platzieren, und die Beschriftungen nur die fünf Zahlen zusammenfassen zu lassen.

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

    Bildbeschreibung hier eingeben

    Da es beim Vergleich verschiedener Gruppen keine zufriedenstellende Lösung für diese Art von Handlung gab, schrieb ich eine function , um dies zu tun.

    Es funktioniert sowohl für gruppierte als auch für nicht gruppierte Daten und akzeptiert zusätzliche grafische Parameter:

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

    Bildbeschreibung hier eingeben

     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) 

    Bildbeschreibung hier eingeben

    Ich habe das Paket ( ggpubr ) gefunden, das für dieses Problem sehr gut zu funktionieren scheint und mehrere Möglichkeiten zum Anzeigen der Daten berücksichtigt.

    Der Link zum Paket ist hier , und in diesem Link finden Sie ein nettes Tutorial, um es zu benutzen. Der Vollständigkeit halber füge ich eines der Beispiele an, die ich reproduziert habe.

    Ich habe das Paket zuerst installiert (es benötigt devtools )

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

    Für das spezielle Beispiel der Darstellung unterschiedlicher Histogramme für verschiedene Gruppen erwähnt es in Bezug auf ggExtra : “Eine Einschränkung von ggExtra besteht darin, dass es nicht mit mehreren Gruppen im Streudiagramm und den Marginalplots umgehen kann. Im nachstehenden R-Code sind wir eine Lösung mit dem cowplot Paket cowplot . ” In meinem Fall musste ich das letztere Paket installieren:

     install.packages("cowplot") 

    Und ich folgte diesem Code:

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

    Was für mich gut funktionierte:

    Iris setzte marginale Histogramme ein

    Bildbeschreibung hier eingeben

    Mit ggstatsplot können Sie leicht attraktive Streudiagramme mit marginalen Histogrammen erstellen (es passt auch und beschreibt ein Modell):

     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 ) 

    Bildbeschreibung hier eingeben

    Oder etwas ansprechender (standardmäßig) 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) ) 

    Bildbeschreibung hier eingeben

    AKTUALISIEREN:

    Wie von @ aickley vorgeschlagen, habe ich die Entwicklungsversion verwendet, um das Diagramm zu erstellen.