По сути, вы просите преобразовать 2D скалярное поле в векторное поле . Есть несколько разных способов сделать это.
Пакет растров содержит функцию terrain
, которая создает новые растровые слои, которые будут давать вам обоим угол желаемого вектора в каждой точке (т.е. аспект ) и его величина ( наклон ). Мы можем использовать небольшую тригонометрию, чтобы преобразовать их в базовые векторы Север-Юг и Восток-Запад, используемые ggquiver
, и добавить их к нашему исходному растру, прежде чем превратить все это в кадр данных. *
terrain_raster <- terrain(r, opt = c('slope', 'aspect'))
r$u <- terrain_raster$slope[] * sin(terrain_raster$aspect[])
r$v <- terr$slope[] * cos(terr$aspect[])
rd <- as.data.frame(r, xy = TRUE)
Однако в большинстве случаев это не дает хорошего сюжета. Если вы сначала не объедините растр, у вас будет один градиент для каждого пикселя изображения, что не будет хорошо отображено. С другой стороны, если вы выполните агрегирование , у вас будет хорошее векторное поле, но ваш растр будет выглядеть «блочно». Следовательно, наличие одного фрейма данных для вашего графика, вероятно, не лучший способ go.
Следующая функция возьмет растр и построит его с наложенным векторным полем. Вы можете настроить степень агрегирования векторного поля, не влияя на растр, и вы можете указать произвольный вектор цветов для вашего растра.
raster2quiver <- function(rast, aggregate = 50, colours = terrain.colors(6))
{
names(rast) <- "z"
quiv <- aggregate(rast, aggregate)
terr <- terrain(quiv, opt = c('slope', 'aspect'))
quiv$u <- terr$slope[] * sin(terr$aspect[])
quiv$v <- terr$slope[] * cos(terr$aspect[])
quiv_df <- as.data.frame(quiv, xy = TRUE)
rast_df <- as.data.frame(rast, xy = TRUE)
print(ggplot(mapping = aes(x = x, y = y, fill = z)) +
geom_raster(data = rast_df, na.rm = TRUE) +
geom_quiver(data = quiv_df, aes(u = u, v = v), vecsize = 1.5) +
scale_fill_gradientn(colours = colours, na.value = "transparent") +
theme_bw())
return(quiv_df)
}
Итак, попробуйте это на вашем примере во Франции после первого определения аналогичную цветовую палитру, мы получаем
pal <- c("#B2182B", "#E68469", "#D9E9F1", "#ACD2E5", "#539DC8", "#3C8ABE", "#2E78B5")
raster2quiver(getData('alt', country = 'FRA', mask = TRUE), colours = pal)
Теперь, чтобы показать, что он работает на произвольном растре (при условии, что имеет назначенную проекцию) давайте проверим это на этом изображении, преобразованном в растровый. На этот раз у нас более низкое разрешение, поэтому мы выбираем меньшее совокупное значение. Мы также выберем прозрачный цвет для самых низких значений, чтобы получить более красивый график:
rast <- raster::raster("https://i.stack.imgur.com/tXUXO.png")
# Add a fake arbitrary projection otherwise "terrain()" doesn't work:
projection(rast) <- "+proj=lcc +lat_1=48 +lat_2=33 +lon_0=-100 +ellps=WGS84"
raster2quiver(rast, aggregate = 20, colours = c("#FFFFFF00", "red"))
* Я должен отметить, что отображение geom_quiver
aestheti c принимает аргументы, называемые u
и v
, которые представляют базисные векторы, указывающие на север и восток. Пакет ggquiver
преобразует их в значения xend
и yend
с использованием stat_quiver
. Если вы предпочитаете использовать значения xend
и yend
, вы можете просто использовать geom_segment
для построения векторного поля, но это усложняет управление внешним видом стрелок. Следовательно, это решение найдет вместо этого величину значений u
и v
.