web-dev-qa-db-fra.com

Ajustement des limites des axes x et y lors de l’ajout de nouvelles courbes à un tracé dans R

J'ai deux jeux de données (df1 et df2) qui sont tracés.

df1 = data.frame(x=c(1:10), y=c(1:10))
df2 = data.frame(x=c(0:13), y=c(0:13)^1.2)

# plot
plot(df1)
# add lines of another dataset
lines(df2)

Certaines valeurs de df2 sont en dehors de la plage de tracé et ne sont donc pas visibles. (Dans cet exemple, je pourrais simplement tracer d'abord df2). J'essaie généralement de connaître les plages de mes données, comme indiqué ci-dessous.

# manual solution
minX = min(df1$x, df2$x)
minY = min(df1$y, df2$y)
maxX = max(df1$x, df2$x)
maxY = max(df1$y, df2$y)

plot (df1, xlim=c(minX, maxX), ylim=c(minY, maxY))
lines(df2)

Lorsque vous avez plusieurs jeux de données, cela devient agaçant. Je me demandais s'il existait un moyen plus simple d'ajuster les plages de l'axe. Dans la première étape, R trouve lui-même les plages d'axe. Existe-t-il également un moyen pour que R ajuste les plages d'axes lorsque de nouveaux jeux de données sont ajoutés?

11
John Garreth

J'aime la solution de @ Roland, mais voici une extension de la solution de @ Glen_b qui fonctionne pour un nombre arbitraire d'ensembles de données, if vous les avez tous dans une liste.

( avertissement : non testé!)

dflist <- list(df1,df2,df3,...)  ## dots are not literal!
plotline <- function(L,...) {    ## here the dots are literal
  ## use them to specify (e.g.) xlab, ylab, other arguments to plot()
  allX <- unlist(lapply(L,"[[","x"))
  allY <- unlist(lapply(L,"[[","y"))
  plot (df1, xlim=range(allX), ylim=range(allY),type="n",...)
  invisible(lapply(L,lines))
}

Cela suppose que vous voulez que tous les jeux de données soient dessinés sous forme de lignes. Si vous souhaitez commencer à spécifier des couleurs, des types de point, etc. distincts, vous pouvez étendre cette fonction, mais vous commencerez à réinventer les packages lattice et ggplot2 à ce stade.

(Si tous vos ensembles de données ont la même taille, vous devriez envisager matplot)

3
Ben Bolker

Vous pouvez utiliser range pour calculer les limites.

À mon humble avis, une meilleure solution:

df1 <- data.frame(x=c(1:10), y=c(1:10))
df2 <- data.frame(x=c(0:13), y=c(0:13)^1.2)

ll <- list(df1,df2)

ll <- lapply(1:length(ll),function(i) {res <- ll[[i]]; res$grp <- i; res})

df <- do.call("rbind",ll)
df$grp <- factor(df$grp)

library(ggplot2)
p1 <- ggplot(df,aes(x=x,y=y,group=grp,col=grp)) + geom_line()
p1
3
Roland

Vous pouvez toujours écrire une fonction:

plotline <- function(df1,df2) {

  minX = min(df1$x, df2$x)
  minY = min(df1$y, df2$y)
  maxX = max(df1$x, df2$x)
  maxY = max(df1$y, df2$y)

  plot (df1, xlim=c(minX, maxX), ylim=c(minY, maxY))
  lines(df2)
}

Ensuite, vous faites juste ceci:

plotline(firstdf,seconddf)

Si vous voulez avoir du chic, vous pouvez même inclure l'argument ... et le transmettre à l'appel de tracé.

2
Glen_b

Examinez la fonction matplot. Elle acceptera une matrice sous la forme x, y ou les deux et effectuera tous les calculs de plage automatiques à votre place. Si vous avez les données dans plusieurs blocs de données, vous pouvez utiliser Sapply pour extraire les éléments clés et former les matrices.

Cette approche est souvent même plus simple que d’utiliser plusieurs fois la fonction de lignes:

df1 <- data.frame(x=1:10, y=1:10)
df2 <- data.frame(x=0:13, y=(0:13)^1.2)
df3 <- data.frame(x= -3:5, y= 5:(-3))

mylist <- list( df1, df2, df3 )
max.n <- max(sapply(mylist,nrow))
tmpfun <- function(df, which.col, n) {
    tmp <- df[[which.col]]
    c(tmp, rep(NA, n-length(tmp)))
}

matplot( sapply(mylist, tmpfun, which.col='x', n=max.n),
        sapply(mylist, tmpfun, which.col='y', n=max.n), type='b' )

Ce qui précède est encore plus simple si toutes les trames de données ont le même nombre de lignes.

L’autre approche mentionnée dans les commentaires consiste à combiner les jeux de données en un seul jeu de données et à utiliser des outils tels que les graphiques en treillis ou ggplot2:

lengths <- sapply(mylist, nrow)
df.all <- do.call(rbind, mylist)
df.all$group <- rep( seq_along(lengths), lengths )

library(lattice)
xyplot( y~x, data=df.all, groups=group, type='b' )

library(ggplot2)
qplot(x,y, colour=factor(group), data=df.all, geom=c('point','path') )

Si tout échoue, vous pouvez utiliser la fonction zoomplot du package TeachingDemos pour modifier les limites des graphiques de base ultérieurement, mais les méthodes ci-dessus sont bien meilleures.

0
Greg Snow