Проблемы с графикой - шкала легенды, разрывы, легенда, десятичные знаки

Я хочу нарисовать кучу растров, и я создал код для настройки разрывов для каждого из них и построения их через цикл 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)

Использование журнала


person Thai    schedule 06.08.2017    source источник
comment
Как вы на самом деле хотите, чтобы это выглядело?   -  person jbaums    schedule 07.08.2017
comment
Я не хочу, чтобы цвета были равномерно распределены по числам, потому что у меня очень мало данных о больших и малых числах и слишком много посередине... Если они распределены поровну, я получаю карту почти без светлого и темно-синего цвета, и все будет быть средне-синим с несколькими синими вариациями. Я хочу один оттенок светло-голубого для одной крайности, один темно-синий для другой крайности и остальную часть синего вдоль данных, где действительно есть данные. Коды, которые я разместил, были моей попыткой сделать это... но я познакомился с программированием и R в прошлом месяце... Мне не хватает основы, хотя я много читал   -  person Thai    schedule 07.08.2017
comment
@jbaums... Вы поняли это объяснение? Пожалуйста, дайте мне знать, если я недостаточно ясно выразился, и я постараюсь исправиться! Заранее спасибо за внимание!   -  person Thai    schedule 07.08.2017
comment
Можно попробовать логарифмическую шкалу. Например: 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)   -  person jbaums    schedule 07.08.2017
comment
Спасибо @jbaums... Мне очень понравилось изучать эту возможность! Но я продолжу пробовать другие варианты, потому что с помощью журнала я теряю простую информацию о количестве осадков в шкале, хотя я могу видеть, где дождей больше..   -  person Thai    schedule 07.08.2017


Ответы (1)


Вы можете избежать масштабирования журнала (как сказали некоторые пользователи), используя функцию classIntervals() из пакета classInt.

Используя функцию 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])

введите здесь описание изображения

Кроме того, у вас есть больше вариантов для выбора, таких как sd, pretty, kmeans, hclust и другие.


Добавление полигонов и точек на график

Во-первых, я сохраню график выше в 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 для получения дополнительной информации.

person aldo_tapia    schedule 08.08.2017
comment
о боже! Добрый Дарвин! Именно то, что мне было нужно! @aldo_tapia, muito obrigada!!! - person Thai; 09.08.2017
comment
levelplot действительно дает лучшие результаты, чем график ... но я познакомился с R в прошлом месяце, поэтому я все еще учусь, и у меня есть некоторые проблемы с добавлением одного графика поверх другого с помощью levelplot, потому что я всегда рисую на одной и той же карте растр, линии для стран из wrld_simpl, пространственных точек и многоугольника... с регулярным сюжетом это легко, я просто делаю plot(x, add=TRUE) для всего, что хочу построить... с levelplot все по-другому. Но я посвящу немного времени изучению levelplot и ggplot как можно скорее! Большое спасибо, @aldo_tapia - person Thai; 09.08.2017
comment
@Thai Позвольте мне помочь вам. Я сейчас далеко от своей машины, но я улучшу свой ответ, как только смогу - person aldo_tapia; 09.08.2017
comment
Я уже использую и изучаю все, чему вы меня научили! Спасибо, @aldo_tapia !!! - person Thai; 10.08.2017