Chciałbym nałożyć 2 wykresy gęstości na tym samym urządzeniu za pomocą R. Jak mogę to zrobić? Przeszukałem sieć, ale nie znalazłem żadnego oczywistego rozwiązania.
Moim pomysłem byłoby odczytanie danych z pliku tekstowego (kolumn), a następnie użycie
plot(density(MyData$Column1))
plot(density(MyData$Column2), add=T)
Albo coś w tym duchu.
r
plot
density-plot
makaron
źródło
źródło
ggplot2
rodziny jest teraz pakiet,ggridges
który może to zrobić.Odpowiedzi:
użyj
lines
do drugiego:upewnij się jednak, że granice pierwszego wątku są odpowiednie.
źródło
ylim
przy użyciu obiektówrange(dens1$y, dens2$y)
gdziedens1
idens2
są zawierające dwa obiekty szacowania gęstości. Użyj tegoylim
w wezwaniu doplot()
.lwd
), typu linii (lty
) lub koloru linii (col
). W tym momencie możesz również rozważyć dodanie legendy, używająclegend()
ggplot2 to kolejny pakiet graficzny, który w całkiem sprytny sposób radzi sobie z takimi problemami, jak problem z zasięgiem, o którym wspomina Gavin. Obsługuje również automatyczne generowanie odpowiednich legend i po prostu ogólnie ma bardziej dopracowany wygląd po wyjęciu z pudełka z mniejszą ręczną manipulacją.
library(ggplot2) #Sample data dat <- data.frame(dens = c(rnorm(100), rnorm(100, 10, 5)) , lines = rep(c("a", "b"), each = 100)) #Plot. ggplot(dat, aes(x = dens, fill = lines)) + geom_density(alpha = 0.5)
źródło
ggplot (melt (MyData), mapping = aes (fill = variable, x = value)) + geom_density (alpha = .5)
dat
w moim środowisku tak go nazwałdat2
... symulowane dane, które udostępniam, działają jednak zgodnie z reklamą.melt()
polecenie pochodzi z pakietureshape2
. W 2011 r.reshape2
Został automatycznie załadowany poggplot2
załadowaniu, ale tak już nie jest, więc musisz to zrobićlibrary(reshape2)
osobno.Dodanie podstawowej wersji grafiki, która dba o limity osi y, dodaje kolory i działa dla dowolnej liczby kolumn:
Jeśli mamy zestaw danych:
myData <- data.frame(std.nromal=rnorm(1000, m=0, sd=1), wide.normal=rnorm(1000, m=0, sd=2), exponent=rexp(1000, rate=1), uniform=runif(1000, min=-3, max=3) )
Następnie, aby wykreślić gęstości:
dens <- apply(myData, 2, density) plot(NA, xlim=range(sapply(dens, "[", "x")), ylim=range(sapply(dens, "[", "y"))) mapply(lines, dens, col=1:length(dens)) legend("topright", legend=names(dens), fill=1:length(dens))
Co daje:
źródło
dens <- apply(myData, 2, density)
nadens <- apply(myData, 2, density, na.rm=TRUE)
i powinna działać.Aby zapewnić kompletny zestaw, oto wersja odpowiedzi Chase'a przy użyciu
lattice
:dat <- data.frame(dens = c(rnorm(100), rnorm(100, 10, 5)) , lines = rep(c("a", "b"), each = 100)) densityplot(~dens,data=dat,groups = lines, plot.points = FALSE, ref = TRUE, auto.key = list(space = "right"))
który tworzy taki wykres:
źródło
data.frame
:densityplot(~rnorm(100)+rnorm(100, 10, 5), plot.points=FALSE, ref=TRUE, auto.key = list(space = "right"))
. Lub dla danych OPdensityplot(~Column1+Column2, data=myData)
.Tak to robię w bazie (tak naprawdę jest to wspomniane w komentarzach pierwszej odpowiedzi, ale pokażę tutaj pełny kod, w tym legendę, ponieważ nie mogę jeszcze komentować ...)
Najpierw musisz uzyskać informacje o maksymalnych wartościach dla osi y z wykresów gęstości. Więc musisz najpierw obliczyć gęstości oddzielnie
dta_A <- density(VarA, na.rm = TRUE) dta_B <- density(VarB, na.rm = TRUE)
Następnie wykreśl je zgodnie z pierwszą odpowiedzią i zdefiniuj wartości minimalne i maksymalne dla osi y, którą właśnie otrzymałeś. (Ustawiam wartość min na 0)
plot(dta_A, col = "blue", main = "2 densities on one plot"), ylim = c(0, max(dta_A$y,dta_B$y))) lines(dta_B, col = "red")
Następnie dodaj legendę w prawym górnym rogu
legend("topright", c("VarA","VarB"), lty = c(1,1), col = c("blue","red"))
źródło
Wziąłem powyższy przykład kraty i wykonałem fajną funkcję. Prawdopodobnie istnieje lepszy sposób, aby to zrobić, zmieniając kształt za pomocą topienia / odlewania. (Skomentuj lub edytuj, jeśli zauważysz poprawę).
multi.density.plot=function(data,main=paste(names(data),collapse = ' vs '),...){ ##combines multiple density plots together when given a list df=data.frame(); for(n in names(data)){ idf=data.frame(x=data[[n]],label=rep(n,length(data[[n]]))) df=rbind(df,idf) } densityplot(~x,data=df,groups = label,plot.points = F, ref = T, auto.key = list(space = "right"),main=main,...) }
Przykładowe użycie:
multi.density.plot(list(BN1=bn1$V1,BN2=bn2$V1),main='BN1 vs BN2') multi.density.plot(list(BN1=bn1$V1,BN2=bn2$V1))
źródło
Możesz skorzystać z
ggjoy
pakietu. Powiedzmy, że mamy trzy różnebeta
dystrybucje, takie jak:set.seed(5) b1<-data.frame(Variant= "Variant 1", Values = rbeta(1000, 101, 1001)) b2<-data.frame(Variant= "Variant 2", Values = rbeta(1000, 111, 1011)) b3<-data.frame(Variant= "Variant 3", Values = rbeta(1000, 11, 101)) df<-rbind(b1,b2,b3)
Możesz uzyskać trzy różne dystrybucje w następujący sposób:
library(tidyverse) library(ggjoy) ggplot(df, aes(x=Values, y=Variant))+ geom_joy(scale = 2, alpha=0.5) + scale_y_discrete(expand=c(0.01, 0)) + scale_x_continuous(expand=c(0.01, 0)) + theme_joy()
źródło
Zawsze, gdy występują problemy z niedopasowanymi granicami osi,
base
należy użyć odpowiedniego narzędzia graficznegomatplot
. Kluczem jest wykorzystanie argumentówfrom
i . To trochę hakerskie, ale dość proste, aby się rzucić:to
density.default
set.seed(102349) x1 = rnorm(1000, mean = 5, sd = 3) x2 = rnorm(5000, mean = 2, sd = 8) xrng = range(x1, x2) #force the x values at which density is # evaluated to be the same between 'density' # calls by specifying 'from' and 'to' # (and possibly 'n', if you'd like) kde1 = density(x1, from = xrng[1L], to = xrng[2L]) kde2 = density(x2, from = xrng[1L], to = xrng[2L]) matplot(kde1$x, cbind(kde1$y, kde2$y))
Dodaj wodotryski jako pożądane (
matplot
akceptuje wszystkie standardoweplot
/par
argumenty, na przykładlty
,type
,col
,lwd
, ...).źródło