在ggplot2中绘制轮廓线平面部分的标签 [英] Drawing labels on flat section of contour lines in ggplot2

查看:144
本文介绍了在ggplot2中绘制轮廓线平面部分的标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

上一个问题中,我转载了用ggplot2生成的等高线图代替(下面的完整示例)。唯一的问题是,我想复制轮廓标签在 contour()中的位置,默认情况下它位于该行的最平坦部分 - 第二个图片可能会显示原因。我被如何设置这个计算难住了。我在这里看到可以抓取用于生成轮廓线,然后可以使用 geom_text()来绘制文字。所以剩下的就是弄清楚如何计算最平坦的部分。想法?

 库(字段)
库(ggplot2)
库(重塑)
library(直接标签)

sumframe <-structure(list(Morph = c(LW,LW,LW,LW,LW,LW ,LW,LW,LW,LW,LW,LW,SW,SW,SW,SW,SW,SW, SW,SW,SW,SW,SW,SW,SW),xvalue = c(4,8,9,9.75,13,​​14,16.25,17.25,18, 23,27,28,28.75,4,8,9,9.75,13,​​14,16.25,17.25,18,23,27,28,28.75),y值= c(17,34,12,21.75,29,7 ,36.25,14.25,24,19,36,14,23.75,17,34,12,21.75,29,7,36.25,14.25,24,19,36,14,23.75),z值= c(126.852666666667,182.843333333333, 147.883333333333,214.686666666667,234.511333333333,1983.345333333333,280.9275,246.425,245.165,247.611764705882,266.068,276.744,283.325,167.889,229.044,218.447777777778,207.393,278.278,203.167,250.495,329.54,282.463,299.825,286.942,372.103,307.068)),其中所述化合物是以下物质: .Names = c(Morph,xvalue,yvalue,zvalue),row.names = c(NA,-26L),class = data.frame)

sumframeLW< -subset(sumframe,Morph ==LW)

#FIELDS CONTOUR PLOT:
surf.teLW< - Tps(cbind(sumframeLW $ xvalue,sumframeLW $ yvalue),sumframeLW $ zvalue,lambda = 0.01)
summary(surf.teLW)
surf.te.outLW< -predict.surface(surf.teLW)
image(surf.te.outLW,col = tim.colors(128),xlim = c(0,38),ylim = c(0,38),zlim = c(100,400),lwd = 5, las = 1,font.lab = 2,cex.lab = 1.3,mgp = c(2.7,0.5,0),font.axis = 1,lab = c(5,5,6),xlab =表达式(X
轮廓(surf.te.outLW,lwd = 2,labcex = 1,add = T)
<表达式(Y值),main =LW图 / code>

 #GGPLOT2 CONTOUR PLOT:
LWsurfm< -melt(surf.te.outLW)
LWsurfm< -rename(LWsurfm,c(value=z,X1=x,X2=y))
LWsurfms< -na.omit(LWsurfm)

LWp <-ggplot(LWsurfms,aes(x,y,z = z))+ geom_tile(aes(fill = z))+ stat_contour(aes(x,y,z = z,color = .level ..),col (color = tim.colors(128))
LWp
LWp <-direct.label(LWp)

p>

解决方案

我创建了一个函数来计算flattest部分,使用 contour()(来自 plot3d ),在 plyr 的帮助下用最平坦的值创建一个数据框,并添加它用 geom_text()手动绘图。为了与 contour()输出完全匹配,需要旋转标签,轮廓线的各部分需要擦除以为标签留出空间,并且需要更正以确保标签不会从轮廓线的边缘脱落。我将在接下来的几个月内完成这些工作(这仍然是一个侧面项目)。

  library(fields)
library(ggplot2)
library(reshape)

sumframe< -structure(list(Morph = c(LW,LW,LW,LW, LW,LW,LW,LW,LW,LW,LW,LW,LW,SW,SW,SW,SW SW,SW,SW,SW,SW,SW,SW,SW,SW,xvalue = c(4,8,9,9.75) ,13,14,16.25,17.25,18,23,27,28,28.75,4,8,9,9.75,13,​​14,16.25,17.25,18,23,27,28,28.75),y值= c(其中, 17,34,12,21.75,29,7,36.25,14.25,24,19,36,14,23.75,17,34,12,21.75,29,7,36.25,14.25,24,19,36, 23.75),z值= c(126.852666666667,182.843333333333,147.883333333333,214.686666666667,234.511333333333,198.345333333333,280.9275,246.425,245.165,247.611764705882,266.068,276.744,283.325,167.889,229.044,218.447777777778,207.393,278.278,203.167,250.495,329.54,282.463 ,299.825,286.942,372.103,307.068)),.Name = c(Morph,xvalue, yvalue,zvalue),row.names = c(NA,-26L),class =data.frame)

#细分,计算曲面,重组ggplot:$ b $ (sumframe,Morph =SW)

surf.teLW <-Tps(cbind(sumframeLW) $ xvalue,sumframeLW $ yvalue),sumframeLW $ zvalue,lambda = 0.01)
surf.te.outLW< -predict.surface(surf.teLW)

surf.teSW< -Tps cbind(sumframeSW $ xvalue,sumframeSW $ yvalue),sumframeSW $ zvalue,lambda = 0.01)
surf.te.outSW< -predict.surface(surf.teSW)

sumframe $ Morph< -as.numeric(as.factor(sumframe $ Morph))

LWsurfm< -melt(surf.te.outLW)
LWsurfm< -rename(LWsurfm,c(value= z,X1=x,X2=y))
LWsurfms <-na.omit(LWsurfm)
LWsurfms [,Morph]< -c LW)

SWsurfm< -melt(surf.te.outSW)
SWsurfm< -rename(SWsurfm,c(value=z,X1=x ,X2=y))
SWsurfms< -na.omit(SWsurfm)
SWsurfms [,Morph]< -c(SW)

LWSWsurf&l t; -rbind(LWsurfms,SWsurfms)
#请注意,我失去了我的单位 - 事情已被重新调整到0到80之间。

LWSWc< -ggplot(LWSWsurf,aes (x,y,z = z))+ facet_wrap(〜Morph)+ geom_contour(color =black,size = 0.6)
LWSWc
#根据用于生成等高线图的数据创建数据框:
tmp3< -ggplot_build(LWSWc)$ data [[1]]

简而言之, tmp3 数据框包含一个向量, tmp3 $ group ,它被用作后续计算的分组变量。在 tmp3 $ group 的每个级别内,差异是使用 flattenb 计算的。生成了一个新的数据框,并且来自该数据框的值通过 geom_text()添加到了图中。

< pre $ lt; code> flattenb< - function(tmp3){
counts = length(tmp3 $ group)
xdiffs = diff(tmp3 $ x)
ydiffs = diff(tmp3 $ y)
avgGradient = ydiffs / xdiffs
squareSum = avgGradient * avgGradient
variance =(squareSum - (avgGradient * avgGradient)/ counts / counts)
data.frame (方差= c(9999999,方差)#99999填充此长度与原始长度相同,并且未选择第一个值

}

tmp3 <-cbind( tmp3,ddply(tmp3,'group',flattenb))
tmp3l< -ddply(tmp3,'group',subset,variance == min(variance))
tmp3l [,Morph]< ; -c(rep(LW,times = 8),rep(SW,times = 8))

LWSWpp <-ggplot(LWSWsurf,aes(x,y,z = z ))
LWSWpp <-LWSWpp + geom_tile(aes(fill = z))+ stat_contour(aes(x,y,z = z,color = .. level ..),color =black,size = 0.6)
LWSWpp <-LWS Wpp + scale_fill_gradientn(colors = tim.colors(128))
LWSWpp <-LWSWpp + geom_text(data = tmp3l,aes(z = NULL,label = level))+ facet_wrap(〜Morph)
LWSWpp


In a previous question, I reproduced a contour plot generated with the fields package, in ggplot2 instead (full example below). The only trouble is, I would like to replicate the placement of the contour labels in contour(), which by default are at the "flattest" part of the line - the second picture might show why. I'm stumped by how to set up that calculation. I see here that it's possible to grab the data used to generate the contour lines, and then geom_text() could be used to plot the text. So what's left is figuring out how to calculate the "flattest" part. Ideas?

library(fields)
library(ggplot2)
library(reshape)
library(directlabels)

sumframe<-structure(list(Morph = c("LW", "LW", "LW", "LW", "LW", "LW", "LW", "LW", "LW", "LW", "LW", "LW", "LW", "SW", "SW", "SW", "SW", "SW", "SW", "SW", "SW", "SW", "SW", "SW", "SW", "SW"), xvalue = c(4, 8, 9, 9.75, 13, 14, 16.25, 17.25, 18, 23, 27, 28, 28.75, 4, 8, 9, 9.75, 13, 14, 16.25, 17.25, 18, 23, 27, 28, 28.75), yvalue = c(17, 34, 12, 21.75, 29, 7, 36.25, 14.25, 24, 19, 36, 14, 23.75, 17, 34, 12, 21.75, 29, 7, 36.25, 14.25, 24, 19, 36, 14, 23.75), zvalue = c(126.852666666667, 182.843333333333, 147.883333333333, 214.686666666667, 234.511333333333, 198.345333333333, 280.9275, 246.425, 245.165, 247.611764705882, 266.068, 276.744, 283.325, 167.889, 229.044, 218.447777777778, 207.393, 278.278, 203.167, 250.495, 329.54, 282.463, 299.825, 286.942, 372.103, 307.068)), .Names = c("Morph", "xvalue", "yvalue", "zvalue"), row.names = c(NA, -26L), class = "data.frame")

sumframeLW<-subset(sumframe, Morph=="LW")

# FIELDS CONTOUR PLOT:
surf.teLW<-Tps(cbind(sumframeLW$xvalue, sumframeLW$yvalue), sumframeLW$zvalue, lambda=0.01)
summary(surf.teLW)
surf.te.outLW<-predict.surface(surf.teLW)
image(surf.te.outLW, col=tim.colors(128), xlim=c(0,38), ylim=c(0,38), zlim=c(100,400), lwd=5, las=1, font.lab=2, cex.lab=1.3, mgp=c(2.7,0.5,0), font.axis=1, lab=c(5,5,6), xlab=expression("X value"), ylab=expression("Y value"),main="LW plot")
contour(surf.te.outLW, lwd=2, labcex=1, add=T)

# GGPLOT2 CONTOUR PLOT:
LWsurfm<-melt(surf.te.outLW)
LWsurfm<-rename(LWsurfm, c("value"="z", "X1"="x", "X2"="y"))
LWsurfms<-na.omit(LWsurfm)

LWp<-ggplot(LWsurfms, aes(x,y,z=z))+geom_tile(aes(fill=z))+stat_contour(aes(x,y,z=z, colour=..level..), colour="black", size=0.6)+scale_fill_gradientn(colours=tim.colors(128))
LWp
LWp<-direct.label(LWp)

解决方案

I created a function to calculate the flattest section using the method for contour() (from plot3d), created a data frame with just the flattest values with help from plyr, and added it manually to the plot with geom_text(). To exactly match the contour() output, the labels need to be rotated, sections of the contour lines need to be erased to make room for the labels, and corrections need to be made to ensure the labels don't fall off the edges of the contour lines. I will work on these over the next couple of months (this is all still a side project).

library(fields)
library(ggplot2)
library(reshape)

sumframe<-structure(list(Morph = c("LW", "LW", "LW", "LW", "LW", "LW", "LW", "LW", "LW", "LW", "LW", "LW", "LW", "SW", "SW", "SW", "SW", "SW", "SW", "SW", "SW", "SW", "SW", "SW", "SW", "SW"), xvalue = c(4, 8, 9, 9.75, 13, 14, 16.25, 17.25, 18, 23, 27, 28, 28.75, 4, 8, 9, 9.75, 13, 14, 16.25, 17.25, 18, 23, 27, 28, 28.75), yvalue = c(17, 34, 12, 21.75, 29, 7, 36.25, 14.25, 24, 19, 36, 14, 23.75, 17, 34, 12, 21.75, 29, 7, 36.25, 14.25, 24, 19, 36, 14, 23.75), zvalue = c(126.852666666667, 182.843333333333, 147.883333333333, 214.686666666667, 234.511333333333, 198.345333333333, 280.9275, 246.425, 245.165, 247.611764705882, 266.068, 276.744, 283.325, 167.889, 229.044, 218.447777777778, 207.393, 278.278, 203.167, 250.495, 329.54, 282.463, 299.825, 286.942, 372.103, 307.068)), .Names = c("Morph", "xvalue", "yvalue", "zvalue"), row.names = c(NA, -26L), class = "data.frame")

# Subdivide, calculate surfaces, recombine for ggplot:
sumframeLW<-subset(sumframe, Morph=="LW")
sumframeSW<-subset(sumframe, Morph="SW")

surf.teLW<-Tps(cbind(sumframeLW$xvalue, sumframeLW$yvalue), sumframeLW$zvalue, lambda=0.01)
surf.te.outLW<-predict.surface(surf.teLW)

surf.teSW<-Tps(cbind(sumframeSW$xvalue, sumframeSW$yvalue), sumframeSW$zvalue, lambda=0.01)
surf.te.outSW<-predict.surface(surf.teSW)

sumframe$Morph<-as.numeric(as.factor(sumframe$Morph))

LWsurfm<-melt(surf.te.outLW)
LWsurfm<-rename(LWsurfm, c("value"="z", "X1"="x", "X2"="y"))
LWsurfms<-na.omit(LWsurfm)
LWsurfms[,"Morph"]<-c("LW")

SWsurfm<-melt(surf.te.outSW)
SWsurfm<-rename(SWsurfm, c("value"="z", "X1"="x", "X2"="y"))
SWsurfms<-na.omit(SWsurfm)
SWsurfms[,"Morph"]<-c("SW")

LWSWsurf<-rbind(LWsurfms, SWsurfms)
# Note that I've lost my units - things have been rescaled to be between 0 and 80.

LWSWc<-ggplot(LWSWsurf, aes(x,y,z=z))+facet_wrap(~Morph)+geom_contour(colour="black", size=0.6)
LWSWc
# Create data frame from data used to generate this contour plot:
tmp3<-ggplot_build(LWSWc)$data[[1]]

In a nutshell, the tmp3 data frame contains a vector, tmp3$group, which was used as a grouping variable for subsequent calculations. Within each level of tmp3$group, the variances were calculated with flattenb. A new data frame was generated, and the values from that data frame were added to the plot with geom_text().

flattenb <- function (tmp3){
    counts = length(tmp3$group)
    xdiffs = diff(tmp3$x)
    ydiffs = diff(tmp3$y)
    avgGradient = ydiffs/xdiffs
    squareSum = avgGradient * avgGradient
    variance = (squareSum - (avgGradient * avgGradient) / counts / counts)
    data.frame(variance = c(9999999, variance) #99999 pads this so the length is same as original and the first values are not selected
    )
}

tmp3<-cbind(tmp3, ddply(tmp3, 'group', flattenb))
tmp3l<-ddply(tmp3, 'group', subset, variance==min(variance))
tmp3l[,"Morph"]<-c(rep("LW", times=8), rep("SW", times=8))

LWSWpp<-ggplot(LWSWsurf, aes(x,y,z=z))
LWSWpp<-LWSWpp+geom_tile(aes(fill=z))+stat_contour(aes(x,y,z=z, colour=..level..), colour="black", size=0.6)
LWSWpp<-LWSWpp+scale_fill_gradientn(colours=tim.colors(128))
LWSWpp<-LWSWpp+geom_text(data=tmp3l, aes(z=NULL, label=level))+facet_wrap(~Morph)
LWSWpp

这篇关于在ggplot2中绘制轮廓线平面部分的标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆