绘图问题 - 图例条形比例、中断、图例、小数

Posted

技术标签:

【中文标题】绘图问题 - 图例条形比例、中断、图例、小数【英文标题】:Plot issues - legend bar scale, breaks, legend, decimals 【发布时间】:2018-01-13 23:34:47 【问题描述】:

我想绘制一堆栅格,我创建了一个代码来调整每个栅格的中断并通过 for 循环绘制它们。但是我得到了一个有问题的色标尺,我的努力并没有有效地解决这个问题。示例:

我的降水量范围从 0 到 11.000...但大部分数据在 0 和 5.000 之间...很少有高达 11.000。所以我需要改变休息时间来捕捉这种变化......更多的休息时间我有更多的数据。

然后我为此创建了一个中断对象。 但是当我绘制栅格时,比例颜色条变得非常糟糕,非常混乱......

#get predictors (These are a way lighter version of mine)
predictors_full<-getData('worldclim', var='bio', res=10)

predic_legends<-c(
"Annual Mean Temperature [°C*10]",
"Mean Diurnal Range [°C]",
"Isothermality",
"Temperature Seasonality [standard deviation]",
"Max Temperature of Warmest Month [°C*10]",
"Min Temperature of Coldest Month [°C*10]",
"Temperature Annual Range [°C*10]",
"Mean Temperature of Wettest Quarter [°C*10]",
"Mean Temperature of Driest Quarter [°C*10]",
"Mean Temperature of Warmest Quarter [°C*10]",
"Mean Temperature of Coldest Quarter [°C*10]",
"Annual Precipitation [mm/year]",
"Precipitation of Wettest Month [mm/month]",
"Precipitation of Driest Month [mm/month]",
"Precipitation Seasonality [coefficient of variation]",
"Precipitation of Wettest Quarter [mm/quarter]",
"Precipitation of Driest Quarter [mm/quarter]",
"Precipitation of Warmest Quarter [mm/quarter]",
"Precipitation of Coldest Quarter [mm/quarter]",
)

# Crop rasters and rename
xmin=-120; xmax=-35; ymin=-60; ymax=35
limits <- c(xmin, xmax, ymin, ymax)
predictors <- crop(predictors_full,limits)

predictor_names<-c("mT_annual","mT_dayn_rg","Isotherm","T_season",
"maxT_warm_M","minT_cold_M","rT_annual","mT_wet_Q","mT_dry_Q",
"mT_warm_Q","mT_cold_Q","P_annual","P_wet_M","P_dry_M","P_season",
"P_wet_Q","P_dry_Q","P_warm_Q","P_cold_Q")

names(predictors)<-predictor_names

#Set a palette
Blues_up<-c('#fff7fb','#ece7f2','#d0d1e6','#a6bddb','#74a9cf','#3690c0','#0570b0','#045a8d','#023858','#233159')
colfunc_blues<-colorRampPalette(Blues_up)

#Create a loop to plot all my Predictor rasters
for (i in 1:19) 
#save a figure
png(file=paste0(predictor_names[[i]],".png"),units="in", width=12, height=8.5, res=300)

#Define a plot area
par(mar = c(2,2, 3, 3), mfrow = c(1,1))

#extract values from rasters
vmax<- maxValue(predictors[[i]])
vmin<-minValue(predictors[[i]])
vmedn=(maxValue(predictors[[i]])-minValue(predictors[[i]]))/2

#breaks 
break1<-c((seq(from=vmin,to= vmedn, length.out = 40)),(seq(from=(vmedn+(vmedn/5)),to=vmax,length.out = 5)))

#plot without the legend because the legend would come out with really messy, with too many marks and uneven spaces
plot(predictors[[i]], col =colfunc_blues(45) , breaks=break1,  margin=FALSE, 
            main =predic_legends[i],legend.shrink=1)
dev.off()

这个数字是循环中所有栅格的 i=12

然后我写了一个不同的代码来为颜色条设置不同的中断

#Plot the raster with no color scale bar    
plot(predictors[[i]], col =colfunc_blues(45) , breaks=break1,  margin=FALSE, 
        main =predic_legends[i],legend=FALSE)

#breaks for the color scale
def_breaks = seq(vmax,vmin,length.out=(10))

#plot only the legend
image.plot(predictors_full[[i]], zlim = c(vmin,vmax), 
             legend.only = TRUE, col = colfunc_greys(30),
             axis.args = list(at = def_breaks, labels =def_breaks,cex.axis=0.5)) 

但这不起作用,因为颜色与地图中的数字并不完全匹配……看看每张地图中 6.000 的颜色……它是不同的。

关于如何进行此操作的任何提示? 我是 R 的新手,所以为了实现我的目标我付出了很多努力...... 另外,我的数字中有很多小数位...如何将其更改为小数点后 2 位?

编辑:@jbaums 教我使用日志...我喜欢,但它还不是我所寻求的

levelplot(predictors[[12]]+1, col.regions=colorRampPalette(brewer.pal(9, 'Blues')), zscaleLog=TRUE, at=seq(1, 4, len=100), margin=FALSE)

【问题讨论】:

您真正希望它是什么样子? 我不希望颜色沿数字均匀分布,因为我的高低数字数据很少,而中间的数据太多......如果它们均匀分布,我会得到一张几乎没有的地图浅蓝色和深蓝色,一切都是“中蓝色”,蓝色变化很少。我想要一个极端的浅蓝色阴影,另一个极端的深蓝色阴影,以及数据中确实存在数据的其余蓝色。我发布的代码是我尝试这样做...但上个月我被介绍到编程和 R...我缺乏基础,虽然我已经阅读了很多 @jbaums... 你明白这个解释吗?请让我知道如果我不够清楚,我会努力做得更好!提前感谢您的关注! 你可以试试对数刻度。例如:library(rasterVis); library(RColorBrewer); levelplot(predictors[[12]]+1, col.regions=colorRampPalette(brewer.pal(9, 'Blues')), zscaleLog=TRUE, at=seq(1, 4, len=100), margin=FALSE) 谢谢@jbaums...我真的很喜欢学习这种可能性!但我会继续尝试其他选项,因为使用日志我会丢失规模中降水量的简单信息,尽管我可以看到哪里下雨更多.. 【参考方案1】:

您可以使用 classInt 包中的 classIntervals() 函数来避免日志缩放(正如一些用户所说的那样)。

使用levelplot()(在我看来结果比raster::plot()函数好):

# Normal breaks
break1 <- classIntervals(predictors[[12]][!is.na(predictors[[12]])], n = 50, style = "equal")

levelplot(predictors[[12]], col.regions=colorRampPalette(brewer.pal(9, 'Blues')), at=break1$brks, margin=FALSE,main =predic_legends[12])

# Using quantiles
break1 <- classIntervals(predictors[[12]][!is.na(predictors[[12]])], n = 50, style = "quantile")

levelplot(predictors[[12]], col.regions=colorRampPalette(brewer.pal(9, 'Blues')), at=break1$brks, margin=FALSE,main =predic_legends[12])

此外,您还有更多选项可供选择,例如sdprettykmeanshclust 等。


添加多边形并指向绘图

首先,我将上面的图保存到p,这个例子的行太长了:

p <- levelplot(predictors[[12]], col.regions=colorRampPalette(brewer.pal(9, 'Blues')), at=break1$brks, margin=FALSE,main =predic_legends[12])

我将使用与您的 wrld_simpl 数据相同的数据作为要添加到绘图中的多边形,我还将创建要添加到绘图中的点。

library(maptools)
library(rgeos)

data(wrld_simpl)
pts <- gCentroid(wrld_simpl, byid = T)

要添加线、多边形、点甚至文本,您可以使用layer() 函数和panel.spplot 对象:

p + layer(sp.polygons(wrld_simpl)) + layer(sp.points(pts))

最后,您还可以更改颜色、填充、符号等:

p + layer(sp.polygons(wrld_simpl,col='firebrick')) + layer(sp.points(pts,pch = 12,col='red'))

查看?panel.spplot了解更多信息。

【讨论】:

天哪!好达尔文!正是我需要的! @aldo_tapia, muito obrigada!!! levelplot 确实产生了比 plot 更好的结果...但是我上个月被介绍给 R,因此我仍在学习,并且我在使用 levelplot 将一个情节添加到另一个情节时遇到了一些麻烦,因为我总是情节在同一张地图中,栅格、来自 wrld_simpl 的国家线、spatialPoints 和多边形...使用 reguar 绘图很容易,我只需为我想要绘制的所有内容执行 plot(x, add=TRUE)... 与 levelplot 不同。但我会花一些时间尽快学习 levelplot 和 ggplot!非常感谢,@aldo_tapia @Thai 让我帮你。我现在离我的机器还很远,但我会尽快改进我的答案 我已经在使用和探索你教给我的一切!谢谢,@aldo_tapia !!!

以上是关于绘图问题 - 图例条形比例、中断、图例、小数的主要内容,如果未能解决你的问题,请参考以下文章

如何设置图例中的项目并使用数据框条形图进行绘图

指定标签和中断时缺少 ggplot scale_fill_identity 图例

当数据中不存在分组变量的所有级别时,绘图之间的颜色比例和图例一致

图例中的空白,同时(使用中断参数)在 R 中使用 plot() 绘制 rasterLayer

如何更改我的 t_map 对象图例中的中断

我想让 r 条形图的图例框水平,但 ncol 不起作用