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.
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?
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))
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
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.
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")
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:
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))
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)
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)
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:
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
)
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)
)
UPDATE:
Zgodnie z sugestią @aickley użyłem wersji rozwojowej do stworzenia fabuły.
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