Scatterplot z marginalnymi histogramami w ggplot2

Czy istnieje sposób tworzenia wykresów z marginalnymi histogramami, tak jak w próbce poniżej w ggplot2? W Matlab jest to funkcja scatterhist() i istnieją odpowiedniki dla R, jak również. Nie widziałem go jednak na ggplot2.

scatterplot z histogramami marginalnymi

Rozpocząłem próbę od stworzenia pojedynczych Wykresów, ale nie wiem, jak je właściwie ułożyć.

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

I uporządkowanie ich za pomocą funkcji zamieszczonej tutaj . Ale krótko mówiąc: Czy istnieje sposób tworzenia te wykresy?

Author: Seb, 2011-12-17

8 answers

Pakiet gridExtra powinien działać tutaj. Zacznij od wykonania każdego z obiektów 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()

Następnie użyj siatki.funkcja Array:

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

wykreśl

 83
Author: oeo4b,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-06 17:11:56

Nie jest to odpowiedź w pełni responsywna, ale bardzo prosta. Ilustruje alternatywną metodę wyświetlania gęstości krańcowych, a także Jak używać poziomów alfa dla wyjścia graficznego obsługującego przezroczystość: {]}

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

Tutaj wpisz opis obrazka

 105
Author: 42-,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-17 18:10:37

To może być trochę późno, ale postanowiłem zrobić pakiet (ggExtra) do tego, ponieważ wymagał trochę kodu i może być nudne do pisania. Pakiet stara się również rozwiązać pewne powszechne problemy, takie jak zapewnienie, że nawet jeśli istnieje tytuł lub tekst jest powiększony, działki nadal będą zgodne ze sobą.

Podstawowa idea jest podobna do tej, którą dały odpowiedzi, ale wykracza nieco poza to. Oto przykład jak dodać histogramy marginalne do losowego zestawu 1000 punktów. Mam nadzieję, że ułatwi to dodawanie histogramów / Wykresów gęstości w przyszłości.

Link do pakietu 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")

Tutaj wpisz opis obrazka

 72
Author: Dean Attali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-31 00:18:27

Jeden dodatek, żeby zaoszczędzić trochę czasu na szukanie ludzi, którzy robią to po nas.

Legendy, etykiety osi, teksty osi, kleszcze sprawiają, że działki oddalają się od siebie, więc twoja fabuła będzie wyglądać brzydko i niespójnie.

Możesz to poprawić, używając niektórych z tych ustawień motywu,

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

I align = "left",

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

Więc wyniki będą wyglądać OK:

przykład

 43
Author: Lorinc Nyitrai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-27 01:02:25

Tylko bardzo mała wariacja na temat Odpowiedzi Bondeddusta , w ogólnym duchu marginalnych wskaźników rozkładu.

Edward Tufte nazwał to użycie wykresów dywanowych "wykresem kropkowym" i ma przykład w VDQI użycia linii osi do wskazania zakresu każdej zmiennej. W moim przykładzie etykiety osi i linie siatki również wskazują rozmieszczenie danych. Etykiety znajdują się na wartościach Tukey ' s five number summary (minimum, lower-hinge, mediana, górny zawias, maksymalny), dając szybkie wrażenie rozłożenia każdej zmiennej.

Te pięć liczb jest więc liczbową reprezentacją kartoteki. Jest to trochę trudne, ponieważ nierównomiernie rozmieszczone linie siatki sugerują, że osie mają skalę nieliniową (w tym przykładzie są liniowe). Być może najlepiej byłoby pominąć linie siatki lub zmusić je do bycia w regularnych miejscach i po prostu pozwolić etykietom pokazać podsumowanie pięciu liczb.

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

Tutaj wpisz opis obrazka

 27
Author: Ben,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:22

Ponieważ nie było satysfakcjonującego rozwiązania dla tego rodzaju wykresu przy porównywaniu różnych grup, napisałem funkcję, Aby to zrobić.

Działa zarówno dla danych pogrupowanych, jak i rozgrupowanych i akceptuje dodatkowe parametry graficzne:

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

Tutaj wpisz opis obrazka

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)

Tutaj wpisz opis obrazka

 8
Author: Hav0k,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-19 11:31:42

Znalazłem pakiet (ggpubr), który wydaje się działać bardzo dobrze dla tego problemu i rozważa kilka możliwości wyświetlania danych.

Link do pakietu znajduje się tutaj , a w ten link znajdziesz fajny samouczek, aby go używać. Dla kompletności załączam jeden z przykładów, które odtworzyłem.

Najpierw zainstalowałem pakiet (wymaga devtools)

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

Dla konkretnego przykładu wyświetlania różnych histogramów dla różnych grup, to wzmianki w odniesieniu do ggExtra: "jednym z ograniczeń ggExtra jest to, że nie może poradzić sobie z wieloma grupami w wykresie rozproszonym i wykresach marginalnych. W poniższym kodzie R udostępniamy rozwiązanie za pomocą pakietu cowplot."W moim przypadku musiałem zainstalować ten ostatni pakiet:

install.packages("cowplot")

I podążałem za tym kawałkiem kodu:

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

Co mi dobrze wyszło:

Iris set marginal histograms scatterplot

Tutaj wpisz opis obrazka

 3
Author: Alf Pascu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-02 01:25:24

Możesz łatwo tworzyć atrakcyjne wykresy z marginalnymi histogramami za pomocą ggstatsplot (będzie również pasował i opisywał model):

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
)

Tutaj wpisz opis obrazka

Lub nieco bardziej atrakcyjne (domyślnie) 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)
)

Tutaj wpisz opis obrazka

UPDATE:

Zgodnie z sugestią @aickley użyłem wersji rozwojowej do stworzenia fabuły.

 1
Author: epo3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-26 16:06:21