Streudiagramm mit Randhistogrammen in ggplot2

137

Gibt es eine Möglichkeit, Streudiagramme mit Randhistogrammen zu erstellen, wie in der folgenden Stichprobe in ggplot2? In Matlab ist es die scatterhist()Funktion und es gibt auch Äquivalente für R. Ich habe es jedoch nicht für ggplot2 gesehen.

Streudiagramm mit Randhistogrammen

Ich habe einen Versuch gestartet, indem ich die einzelnen Diagramme erstellt habe, weiß aber nicht, wie ich sie richtig anordnen soll.

 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 deren Anordnung mit der Funktion geschrieben hier . Um es kurz zu machen: Gibt es eine Möglichkeit, diese Grafiken zu erstellen?

Seb
quelle
@ DWin richtig danke - aber ich denke, das ist so ziemlich die Lösung, die ich in meiner Frage gegeben habe. Ich mag jedoch die geom_rag () denken sehr von Ihnen unten gegeben!
Seb
1
aus einem aktuellen Blog-Beitrag, der das gleiche Thema enthält: blog.mckuhn.de/2009/09/learning-ggplot2-2d-plot-with.html sieht auch ganz gut aus :)
Seb
Die neue Website für die Grafikgalerie
IRTFM
@Seb Sie könnten erwägen, die "akzeptierte Antwort" in die über ggExtra-Paket zu ändern, wenn Sie denken, dass es sinnvoll ist
DeanAttali

Antworten:

93

Das gridExtraPaket sollte hier funktionieren. Beginnen Sie, indem Sie jedes der ggplot-Objekte 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()

Verwenden Sie dann die Funktion grid.arrange:

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

Handlung

oeo4b
quelle
6
1+ zur Demonstration der Platzierung, aber Sie sollten die Zufallsstichprobe nicht erneut durchführen, wenn die innere Streuung mit den Randhistogrammen "ausgerichtet" werden soll.
IRTFM
1
Du hast recht. Sie werden jedoch aus derselben Verteilung abgetastet, sodass die Randhistogramme theoretisch mit dem Streudiagramm übereinstimmen sollten.
oeo4b
8
In der "Theorie" werden sie asymptotisch "übereinstimmen"; In der Praxis ist die Anzahl der Übereinstimmungen unendlich gering. Es ist sehr einfach, das bereitgestellte Beispiel zu verwenden xy <- data.frame(x=rnorm(300), y=rt(300,df=2) )und data=xyin den ggplot-Aufrufen zu verwenden.
IRTFM
7
Ich würde diese Lösung nicht empfehlen, da die Plotachsen normalerweise nicht genau ausgerichtet sind. Hoffentlich erleichtern zukünftige Versionen von ggplot2 das Ausrichten der Achsen oder ermöglichen sogar benutzerdefinierte Anmerkungen an den Seiten eines Plotfelds (wie benutzerdefinierte Funktionen der sekundären Achse im Gitter).
baptiste
9
Nein, das würden sie im Allgemeinen nicht. ggplot2 gibt derzeit eine unterschiedliche Bedienfeldbreite aus, die sich je nach Umfang der Achsenbeschriftungen usw. ändert. Schauen Sie sich ggExtra :: align.plots an, um zu sehen, welche Art von Hack derzeit zum Ausrichten von Achsen erforderlich ist.
baptiste
115

Dies ist keine vollständig reaktionsschnelle Antwort, aber sehr einfach. Es zeigt eine alternative Methode zur Anzeige von Randdichten und zur Verwendung von Alpha-Levels für grafische Ausgaben, die Transparenz unterstützen:

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

Geben Sie hier die Bildbeschreibung ein

IRTFM
quelle
5
Das ist eine interessante Art, die Dichte zu zeigen. Vielen Dank für das Hinzufügen dieser Antwort. :)
Michelle
21
Es sollte beachtet werden, dass diese Methode viel üblicher ist als das Erstellen von Randhistogrammen. In der Tat ist Teppichplot in veröffentlichten Artikeln üblich, in denen ich noch nie einen veröffentlichten Artikel mit marginalen Historgrammen gesehen habe.
Xu Wang
Sehr interessante und intuitive alternative Antwort! Und sehr einfach! Kein Wunder, dass es noch mehr Stimmen gibt als die richtige Antwort. Mein Verständnis ist, dass dies im Wesentlichen eine eindimensionale Heatmap ist : Die Teppiche sind überall dort dunkler, wo sie überfüllt sind. Meine einzige Sorge wäre, dass die Auflösung der Heatmap nicht so hoch ist wie die eines Histogramms. z.B. Wenn das Grundstück klein ist, werden alle Teppiche zusammengedrückt, was es schwierig macht, die Verteilung wahrzunehmen. Während das Histogramm nicht unter der Einschränkung leidet. Danke für die Idee!
HongboZhu
93

Dies mag etwas spät sein, aber ich habe mich dazu entschlossen, ein Paket ( ggExtra) dafür zu erstellen, da es ein bisschen Code enthält und das Schreiben mühsam sein kann. Das Paket versucht auch, einige häufig auftretende Probleme zu lösen, z. B. sicherzustellen, dass die Diagramme auch dann in einer Linie zueinander stehen, wenn ein Titel vorhanden ist oder der Text vergrößert wird.

Die Grundidee ähnelt der Antwort hier, geht aber etwas darüber hinaus. Hier ist ein Beispiel für das Hinzufügen von Randhistogrammen zu einer zufälligen Menge von 1000 Punkten. Hoffentlich erleichtert dies das Hinzufügen von Histogrammen / Dichtediagrammen 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")

Geben Sie hier die Bildbeschreibung ein

DeanAttali
quelle
1
Vielen Dank für das Paket. Es funktioniert sofort!
Heroxbd
Ist es mit diesem Paket möglich, Grenzdichtediagramme für Objekte zu zeichnen, die nach Farben gruppiert sind?
GegznaV
Nein, es hat nicht diese Art von Logik
DeanAttali
1
@jjrr Ich bin nicht sicher, was nicht funktioniert und welche Probleme Sie haben, aber es gab kürzlich ein Problem mit Github über das Rendern in einem Notizbuch und es gibt auch eine Lösung. Dies könnte nützlich sein. github.com/daattali/ ggExtra / Issues / 89
DeanAttali
1
@GegznaV, wenn Sie immer noch nach einer Möglichkeit suchen, Randdichtediagramme nach Farben zu gruppieren, ist dies mit ggExtra 0.9 möglich: ggMarginal (p, Typ = "Dichte", Größe = 5, Gruppenfarbe = WAHR)
MartineJ
46

Eine Ergänzung, nur um etwas Suchzeit für Leute zu sparen, die dies nach uns tun.

Legenden, Achsenbeschriftungen, Achsentexte und Häkchen lassen die Diagramme voneinander abweichen, sodass Ihr Diagramm hässlich und inkonsistent aussieht.

Sie können dies korrigieren, indem Sie einige dieser Themeneinstellungen 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 Skalen ausrichten,

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

Die Ergebnisse sehen also in Ordnung aus:

ein Beispiel

Lorinc Nyitrai
quelle
3
Sehen Sie dies für eine zuverlässigere Lösung zum Ausrichten von Handlungstafeln
Baptiste
Ja. Meine Antwort ist veraltet, verwenden Sie die vorgeschlagene Lösung @baptiste.
Lorinc Nyitrai
@ LorincNyitrai Können Sie bitte Ihren Code für die Erstellung dieses Diagramms teilen? Ich habe auch eine Bedingung, unter der ich ein Präzisions-Rückruf-Streudiagramm in ggplot2 mit einer Randverteilung für 2 Gruppen erstellen möchte, aber ich kann keine Randverteilung für 2 Gruppen durchführen. Danke
Neuling
@Newbie, diese Antwort ist 3 Jahre alt, so veraltet wie möglich. Verwenden Sie rdocumentation.org/packages/gtable/versions/0.2.0/topics/gtable oder ähnliches.
Lorinc Nyitrai
29

Nur eine sehr geringfügige Abweichung von BondedDusts Antwort im allgemeinen Sinne marginaler Verteilungsindikatoren.

Edward Tufte hat diese Verwendung von Teppichplots als "Punkt-Strich-Plot" bezeichnet und in VDQI ein Beispiel für die Verwendung der Achsenlinien zur Angabe des Bereichs jeder Variablen angegeben. In meinem Beispiel geben die Achsenbeschriftungen und Gitterlinien auch die Verteilung der Daten an. Die Beschriftungen befinden sich bei den Werten der Fünf-Zahlen-Zusammenfassung von Tukey (Minimum, unteres Scharnier, Median, oberes Scharnier, Maximum) und geben einen schnellen Eindruck von der Streuung jeder Variablen.

Diese fünf Zahlen sind somit eine numerische Darstellung eines Boxplots. Es ist etwas schwierig, da die ungleichmäßig verteilten Gitterlinien darauf hindeuten, dass die Achsen eine nichtlineare Skalierung haben (in diesem Beispiel sind sie linear). Vielleicht ist es am besten, Gitterlinien wegzulassen oder sie an normalen Stellen zu erzwingen und die Beschriftungen nur die Zusammenfassung mit fünf Zahlen anzeigen 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))

Geben Sie hier die Bildbeschreibung ein

Ben
quelle
12

Da es beim Vergleich verschiedener Gruppen keine zufriedenstellende Lösung für diese Art von Handlung gab, schrieb ich eine Funktion , 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)

Geben Sie hier die Bildbeschreibung ein

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)

Geben Sie hier die Bildbeschreibung ein

Hav0k
quelle
9

Ich habe das package ( ggpubr) gefunden, das für dieses Problem sehr gut zu funktionieren scheint, und es berücksichtigt verschiedene Möglichkeiten, die Daten anzuzeigen.

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

Ich habe das Paket zuerst installiert (es erfordert devtools )

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

Für das spezielle Beispiel der Anzeige verschiedener Histogramme für verschiedene Gruppen wird Folgendes erwähnt ggExtra: "Eine Einschränkung ggExtrabesteht darin, dass nicht mehrere Gruppen im Streudiagramm und in den Randdiagrammen behandelt werden können. Im folgenden R-Code stellen wir a Lösung mit demcowplot Paket. " 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 funktioniert hat:

Iris stellte Randhistogramme Streudiagramm ein

Geben Sie hier die Bildbeschreibung ein

Alf Pascu
quelle
Was müssten Sie tun, um das Grundstück in der Mitte zu einem Quadrat zu machen?
JAQuent
Die Form der Punkte meinst du? Versuchen Sie , das Argument shape = 19in ggscatter. Codes für Formen hier
Alf Pascu
7

Mit ggstatsplot können Sie auf einfache Weise attraktive Streudiagramme mit Randhistogrammen erstellen (es passt auch zu einem Modell und beschreibt es):

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
)

Geben Sie hier die Bildbeschreibung ein

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

Geben Sie hier die Bildbeschreibung ein

AKTUALISIEREN:

Wie von @aickley vorgeschlagen, habe ich die Entwicklungsversion verwendet, um den Plot zu erstellen.

epo3
quelle
1
Das Histogramm auf der y-Achse ist falsch, da es lediglich eine Kopie des Histogramms auf der x-Achse ist. Dies wurde erst kürzlich behoben . Github.com/kassambara/ggpubr/issues/85 .
Aickley
7

Dies ist eine alte Frage, aber ich dachte, es wäre nützlich, hier ein Update zu veröffentlichen, da ich kürzlich auf dasselbe Problem gestoßen bin (danke an Stefanie Mueller für die Hilfe!).

Die am besten bewertete Antwort mit gridExtra funktioniert, aber das Ausrichten von Achsen ist schwierig / hackig, wie in den Kommentaren ausgeführt wurde. Dies kann jetzt mit dem Befehl ggMarginal aus dem Paket ggExtra gelöst werden:

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

Geben Sie hier die Bildbeschreibung ein

Victoria Auyeung
quelle
Ich habe gerade festgestellt, dass dies vom ursprünglichen Entwickler des ggExtra-Pakets in einer anderen Antwort veröffentlicht wurde. Ich würde empfehlen, stattdessen die akzeptierte Antwort zu geben, aus dem Grund, den ich oben erklärt habe!
Victoria Auyeung
6

Ich habe diese Optionen ausprobiert, war aber mit den Ergebnissen oder dem unordentlichen Code, den man verwenden müsste, um dorthin zu gelangen, nicht zufrieden. Zum Glück hat Thomas Lin Pedersen gerade ein Paket namens Patchwork entwickelt , das die Arbeit auf ziemlich elegante Weise erledigt.

Wenn Sie ein Streudiagramm mit Randhistogrammen erstellen möchten, müssen Sie diese drei Diagramme zunächst separat erstellen.

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

Sie müssen nur noch diese Diagramme mit einem einfachen hinzufügen +und das Layout mit der Funktion festlegen plot_layout().

library(patchwork)

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

Die Funktion plot_spacer()fügt der oberen rechten Ecke ein leeres Diagramm hinzu. Alle anderen Argumente sollten selbsterklärend sein.

Geben Sie hier die Bildbeschreibung ein

Da Histogramme stark von der gewählten Binbreite abhängen, könnte man argumentieren, Dichtediagramme zu bevorzugen. Mit einigen kleinen Modifikationen würde man zB für Eye-Tracking-Daten eine schöne Darstellung bekommen.

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

Geben Sie hier die Bildbeschreibung ein

Obwohl die Daten zu diesem Zeitpunkt noch nicht bereitgestellt werden, sollten die zugrunde liegenden Prinzipien klar sein.

j3ypi
quelle
4

Um auf der Antwort von @ alf-pascu aufzubauen, bietet das manuelle Einrichten und Anordnen jedes Diagramms cowplotviel Flexibilität sowohl in Bezug auf das Haupt- als auch in das Randdiagramm (im Vergleich zu einigen anderen Lösungen). Ein Beispiel ist die Verteilung nach Gruppen. Das Ändern des Hauptdiagramms in ein Diagramm mit 2D-Dichte ist ein weiteres.

Im Folgenden wird ein Streudiagramm mit (richtig ausgerichteten) Randhistogrammen erstellt.

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

Streudiagramm mit Randhistogrammen

Um stattdessen ein Diagramm mit 2D-Dichte zu zeichnen, ändern Sie einfach das Hauptdiagramm.

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

Geben Sie hier die Bildbeschreibung ein

crsh
quelle
3

Eine andere Lösung mit ggpubrund cowplot, aber hier erstellen wir Diagramme mit cowplot::axis_canvasund fügen sie dem ursprünglichen Diagramm hinzu mit 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)

Geben Sie hier die Bildbeschreibung ein

PoGibas
quelle
2

Heutzutage gibt es mindestens ein CRAN-Paket, das das Streudiagramm mit seinen Randhistogrammen erstellt.

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

Beispielplot von ScatterHist

Pere
quelle
0

Sie können die interaktive Form von ggExtra::ggMarginalGadget(yourplot) Boxplots, Violinplots, Dichtediagrammen und Histogrammen verwenden und ganz einfach zwischen diesen wählen.

so wie das

Allan
quelle