Gráfico tridimensional com contornos de nível

May 22, 2012
By

This post was kindly contributed by Ridículas - go there to comment and to read the full post.

Peso de 100 grãos em função do nível de saturação de água no solo e conteúdo de potássio fornecido pela adubação. Linhas no plano inferior representam a projeção das linhas de mesmo valor para peso de 100 grãos.

Nesse post vou apresentar uma função para adicionar contornos de nível em gráficos tridimensionais gerados pela lattice::wireframe(). Para ilustrar o uso da função eu fiz um ajuste de modelo de regressão múltipla aos dados do experimento com soja. Esses dados eu já usei em várias matérias aqui no Ridículas. Uma vez ajustado o modelo, os valores preditos são então representados pela wireframe() usando o panel.3d.contour que foi uma função que aprimorei das leituras que fiz das mensagens da r-help.

Um gráfico tridimensional como este impressiona quem o vê, porém esteja ciente das más impressões que um gráfico tridimensional pode dar pois ele não é de fato tridimensional e sim uma projeção tridimensional em um plano, o que acarreta algumas deformações. Todavia, achei por bem documentar e expor a função mas isso não significa que esta é a melhor representação. A função permite colocar os contornos no plano abaixo, acima e sobre a superfície (bottom, top, on). Tenha cuidado ao escolher o ângulo de observação do gráfico (screen=) e controle a amplitude do eixo z (zlim=) para que a superfície não esconda a projeção abaixo. Confira os resultados no CMR abaixo. Até a próxima ridícula.

#-----------------------------------------------------------------------------
# leitura dos dados

soja <- read.table("http://www.leg.ufpr.br/~walmes/cursoR/cnpaf/soja.txt",
                   header=TRUE, sep="\t", dec=",")
str(soja)

#-----------------------------------------------------------------------------
# ver o peso de 100 grãos

require(lattice)

xyplot(pesograo~potassio, groups=agua, data=soja, type=c("p","a"))
xyplot(pesograo~potassio|agua, data=soja, type=c("p","a"))

#-----------------------------------------------------------------------------
# ajuste de um modelo polinomial nos dois fatores

m0 <- lm(pesograo~bloco+poly(agua,2)*poly(potassio,2), data=soja)
par(mfrow=c(2,2)); plot(m0); layout(1)

anova(m0)
summary(m0)

m1 <- lm(pesograo~bloco+(agua+I(agua^2))*potassio+I(potassio^2), data=soja)
par(mfrow=c(2,2)); plot(m1); layout(1)

anova(m0, m1)
summary(m1)

#-----------------------------------------------------------------------------
# fazendo a predição

pred <- expand.grid(bloco="I", agua=seq(37.5,62.5,l=30),
                    potassio=seq(0,180,l=30))
pred$y <- predict(m1, newdata=pred)

#-----------------------------------------------------------------------------
# vendo a superfície ajustada

source("http://www.leg.ufpr.br/~walmes/ridiculas/ridiculas_functions.R")
args(panel.3d.contour)
body(panel.3d.contour)

require(RColorBrewer)

colr <- brewer.pal(11, "Spectral")
colr <- colorRampPalette(colr, space="rgb")

zlab <- "Peso de 100 grãos"
xlab <- "Potássio no solo"
ylab <- "Nível de saturação de água"

#png(file="f034.png", width=500, height=500)
wireframe(y~potassio*agua, data=pred,
          scales=list(arrows=FALSE), zlab=list(zlab, rot=90),
          xlab=list(xlab, rot=24), ylab=list(ylab, rot=-37),
          zlim=c(5,16), col="gray50", col.contour=1,
          panel.3d.wireframe="panel.3d.contour", type=c("on","bottom"),
          col.regions=colr(100),  drape=TRUE,
          screen=list(z=40, x=-70))
#dev.off()

#-----------------------------------------------------------------------------


Tags: , ,

Comments are closed.