如何在R中创建如下图形?

时间:2016-05-17 03:01:16

标签: r

假设我有这样的数据。

v[180][180]

我想创建一个图表,显示不同时间点的两个实验组中每个实验组的平均重量,以及每个平均重量的标准误差条。我希望将每个组的平均值显示为由一条线连接的点,其中"天"在x轴和"重量'在y轴"。最终产品看起来应该是这样的。

3 个答案:

答案 0 :(得分:1)

你可以这样做。

# Simulate data
set.seed(23)
n <- 5
group1 <- rnorm(n, 100, 5)
group2 <- rnorm(n, 100, 5)
group1.se <- runif(n, 0.5, 3)
group2.se <- runif(n, 0.5, 3)

# Make line plots
x <- c(1:n)
plot(group1 ~ x, ylim=c(90, 115), type="b", lwd=2, col="red", ylab="weights", xlab="days")
lines(group2 ~ x, type="b", lwd=2, pch=2, col="blue")

# Add standard error bars
arrows(x0=x, y0=group1+0.5, y1=group1+group1.se, length=0.05, angle=90, col="lightpink")
arrows(x0=x, y0=group1-0.5, y1=group1-group1.se, length=0.05, angle=90, col="lightpink")
arrows(x0=x, y0=group2+0.5, y1=group2+group2.se, length=0.05, angle=90, col="lightblue")
arrows(x0=x, y0=group2-0.5, y1=group2-group2.se, length=0.05, angle=90, col="lightblue")

# Add legend
legend("bottomright", legend=c("group1", "group2"), col=c("red", "blue"), lty=1)

答案 1 :(得分:1)

如果你对API有所了解,你可以对基础R图形做任何事情。

plot

## define data
x <- 0:14;
dat <- list(
    Sentinel=list(
        mean=c(-0.95,-0.15,-0.40,-0.10,-1.30,-0.95,-1.10,-0.60,-1.10,-1.20, 0.30,-0.50,-2.60, 0.10,-0.95),
        sd  =c( 0.55, 0.55, 1.40, 0.25, 0.60, 1.20, 0.40, 1.00, 0.80, 0.15, 0.25, 0.22, 0.52, 0.30, 1.50),
        pch=22L, pt.cex=1.7, pt.lwd=2.5, pt.bg='white'
    ),
    Infected=list(
        mean=c(-1.35, 0.50,-0.26,-0.05,-0.40,-0.94, 0.55, 0.55,-0.48, 0.23,-1.30,-0.23,-1.05, 0.40, 0.20),
        sd  =c( 0.70, 0.15, 0.70, 0.27, 0.87, 0.50, 0.80, 0.70, 0.50, 0.28, 0.40, 0.45, 1.02, 0.45, 0.35),
        pch=21L, pt.cex=1.4, pt.lwd=2.5, pt.bg='#5555BB'
    )
);

## plot parameters
xoff <- 1;
xlim <- c(0-xoff,14+xoff);
ylim <- c(-4,2);
xticks <- seq(x[1L],x[length(x)],2);
yticks <- -4:2;
datline.lwd <- 2;
err.spread <- 0.12;
err.lwd <- 2.2;
err.col <- '#777777';

## helper function
errorbar <- function(x,mean,sd) {
    segments(x,mean-sd,y1=mean+sd,lwd=err.lwd,col=err.col);
    segments(x-err.spread,mean-sd,x1=x+err.spread,lwd=err.lwd,col=err.col);
    segments(x-err.spread,mean+sd,x1=x+err.spread,lwd=err.lwd,col=err.col);
}; ## end errorbar()

## plot
plot(NA,xlim=xlim,ylim=ylim,xaxs='i',yaxs='i',axes=F,ann=F);
for (prop in names(dat)) {
    d <- dat[[prop]];
    lines(x,d$mean,lwd=datline.lwd);
    errorbar(x,d$mean,d$sd);
    points(x,d$mean,pch=d$pch,cex=d$pt.cex,lwd=d$pt.lwd,bg=d$pt.bg);
}; ## end for
axis(1L,xticks,cex.axis=1.3,lwd=3,col='#777777');
mtext('Days post Infection-Aerosol Group',1L,2.3,cex=1.47);
axis(2L,yticks,cex.axis=1.3,lwd=3,col='#777777',las=1L);
mtext('Change in Temperature (Fahrenheit)',2L,2.3,cex=1.47);
rect(xlim[1L],ylim[1L],xlim[2L],ylim[2L],lwd=4,border='#777777',xpd=NA);
lp <- c('pch','pt.cex','pt.lwd','pt.bg');
do.call(legend,c(list(11.7,1.7,names(dat),bty='n',adj=0.1,lwd=datline.lwd),setNames(nm=lp,lapply(lp,function(p) sapply(dat,`[[`,p)))));

您的新随机测试数据涵盖了不同的范围,因此我们必须调整一些内容以使绘图代码有效。

plot2

## OP's new randomized input
set.seed(23L);
N <- 5L;
data <- data.frame(group1=rnorm(N,100,5),group2=rnorm(N,100,5),group1.se=runif(N,0.5,3),group2.se=runif(N,0.5,3));

## transfer to dat
x <- seq_len(nrow(data))-1L;
dat <- list(
    group1=list(
        mean=data$group1,
        sd  =data$group1.se,
        pch=22L, pt.cex=1.7, pt.lwd=2.5, pt.bg='white'
    ),
    group2=list(
        mean=data$group2,
        sd  =data$group2.se,
        pch=21L, pt.cex=1.4, pt.lwd=2.5, pt.bg='#5555BB'
    )
);

## plot parameters
xoff <- 1;
xlim <- c(x[1L]-xoff,x[length(x)]+xoff);
ylim <- c(95,113);
xticks <- seq(x[1L],x[length(x)]);
yticks <- seq(ylim[1L],ylim[2L]);
datline.lwd <- 2;
err.spread <- 0.12;
err.lwd <- 2.2;
err.col <- '#777777';

## helper function
errorbar <- function(x,mean,sd) {
    segments(x,mean-sd,y1=mean+sd,lwd=err.lwd,col=err.col);
    segments(x-err.spread,mean-sd,x1=x+err.spread,lwd=err.lwd,col=err.col);
    segments(x-err.spread,mean+sd,x1=x+err.spread,lwd=err.lwd,col=err.col);
}; ## end errorbar()

## plot
plot(NA,xlim=xlim,ylim=ylim,xaxs='i',yaxs='i',axes=F,ann=F);
for (prop in names(dat)) {
    d <- dat[[prop]];
    lines(x,d$mean,lwd=datline.lwd);
    errorbar(x,d$mean,d$sd);
    points(x,d$mean,pch=d$pch,cex=d$pt.cex,lwd=d$pt.lwd,bg=d$pt.bg);
}; ## end for
axis(1L,xticks,cex.axis=1.3,lwd=3,col='#777777');
mtext('Days',1L,2.3,cex=1.47);
axis(2L,yticks,cex.axis=1.3,lwd=3,col='#777777',las=1L);
mtext('Weight',2L,2.7,cex=1.47);
rect(xlim[1L],ylim[1L],xlim[2L],ylim[2L],lwd=4,border='#777777',xpd=NA);
lp <- c('pch','pt.cex','pt.lwd','pt.bg');
do.call(legend,c(list(3.7,99,names(dat),bty='n',adj=0.1,lwd=datline.lwd),setNames(nm=lp,lapply(lp,function(p) sapply(dat,`[[`,p)))));

答案 2 :(得分:1)

这是一个ggplot2解决方案。为了提供一个可重复的例子,我使用了数据集BodyWeight{nlme},以及不同日粮中Rat重量随时间变化的数据。

library(data.table)
library(ggplot2)
library(ggthemes)
library(nlme)


data(BodyWeight) # get the data
setDT(BodyWeight) # convert into data.table


# summarize your data into the information you want, getting stats by each time and Diet group
  df <- BodyWeight[, .( mean= mean(weight),
                       SE_upper = mean(weight) + sd(weight)/sqrt(length(weight)),
                       SE_lower = mean(weight) - sd(weight)/sqrt(length(weight))), 
                   by=.(Time,Diet)]


# Plot
  ggplot(data=df, aes(x=Time, y=mean, group= Diet)) + 
    geom_errorbar( aes(ymin=SE_lower, ymax=SE_upper), color="gray40") +
    geom_line( color="gray10" ) + 
    geom_point( aes(shape=Diet, color=Diet),  size=3) +
    theme_bw() +
    theme(panel.grid = element_blank()) +
    labs(x = "Days of Diet", y = "Weight")

如果你想调整情节,ggplot2非常灵活,well documented有很多例子。

enter image description here