Introdução

Neste tutorial mostra-se como plotar dados categóricos armazenados no formato raster. Este tipo de dados é comum para representação de classes de vegetação, bacias hidrográficas, tipo de solos, ou qualquer outro plano de informação dividida em classes, ou categorias, e expresso em caracteres ou números inteiros. No exemplo abaixo, será usado um raster de subbacias hidrográficas, cada subbacia hidrográfica é identificada por dois algarismos.

Pré-requisitos

Para visualização de dados categóricos com várias categorias é conveniente usar paletas de cores aleatórias. O pacote randomcoloR fornece paletas de cores com essa proposta. Para utilizá-lo no R, precisamos instalar a biblioteca linux libv8-3.14-dev1.

$#(Debian, Ubuntu)
$ sudo apt-get install libv8-3.14-dev

Com a biblioteca V8 instalada, podemos instalar o pacote randomcoloR. Se você não possui o pacote raster instalado aproveite para instalá-lo também. Para usar as outras opções de plots seraõ necessários os pacotes rasterVis e ggplot2.

install.packages("randomcoloR")
install.packages("raster")
install.packages("rasterVis")
install.packages("ggplot2")

Agora é necessário carregar os pacotes.

library(randomcoloR)
library(raster)
# para reproduzir opção 2
library(rasterVis)
# para reproduzir opção 3
library(ggplot2)

Dados

Os dados usados nesse tutorial referem-se a um raster contendo códigos de subbacias. O arquivo está no formato ascii grid.

O arquivo está armazenado no link abaixo e será baixado na pasta /home/lsi/Downloadscom os comandos abaixo.

# nome do arquivo raster em formato ascii grid
FILENAME <- "basin2.asc"
# caminho onde será salvo o arquivo
dest_file <- file.path("~/Downloads", FILENAME)
# link do dropbox onde o arquivo está armazenado
data_url <- "https://www.dropbox.com/s/yz1o9q5a2i9e72f/FILENAME?dl=1"
# download
download.file(gsub("FILENAME", FILENAME, data_url),
  destfile = dest_file
)
# verifica se o arquivo foi salvo
file.exists(dest_file)
#> [1] TRUE

Importamos o arquivo ~/Downloads/basin2.asc com a função raster() do pacote raster.

# importando raster ascii grid
bacias <- raster(dest_file)
bacias
#> class       : RasterLayer 
#> dimensions  : 50, 89, 4450  (nrow, ncol, ncell)
#> resolution  : 1000, 1000  (x, y)
#> extent      : 1345500, 1434500, -887500, -837500  (xmin, xmax, ymin, ymax)
#> coord. ref. : NA 
#> data source : /home/hidrometeorologista/Downloads/basin2.asc 
#> names       : basin2 
#> values      : -2147483648, 2147483647  (min, max)
# plot do pacote raster para valores numéricas contínuas
plot(bacias)

O plot gerado não permite distinguir as subbacias hidrográficas. Quantas subacias são mostradas?

Opção 1: plot() do pacote raster

Para melhor visualização das subbacias hidrográficas vamos utilizar a função distinctColorPalette(). Essa função tem como argumento o número de cores. Neste exemplo corresponde ao número de subbacias. Vamos determinar o total de subbacias.

# códigos de cada subbacia
bacias_id <- sort(unique(values(bacias)))
bacias_id
#>  [1] 11 12 13 14 15 16 17 18 19 21 22 23 24 25 26 27 28 29 31 32 33 34 35
#> [24] 36 37 38 39 41 42 43 44 45 46 47 48 49 51 52 53 54 55 56 57 58 59 61
#> [47] 62 63 64 65 66 67 68 69 71 72 73 74 75 76 77 78 79 81 82 83 84 85 86
#> [70] 87 88 89 91 92 93 94 95 96 97 98 99
# num. de subbacias
n_bacias <- length(bacias_id)
n_bacias
#> [1] 81

Com o número de cores podemos construir a paleta de cores e plotar o raster passando a paleta de cores através do argumento col.

cores <- distinctColorPalette(n_bacias)
bacias_id_brks <- bacias_id
names(bacias_id_brks) <- as.character(bacias_id_brks)
bacias_id_brks
#> 11 12 13 14 15 16 17 18 19 21 22 23 24 25 26 27 28 29 31 32 33 34 35 36 37 
#> 11 12 13 14 15 16 17 18 19 21 22 23 24 25 26 27 28 29 31 32 33 34 35 36 37 
#> 38 39 41 42 43 44 45 46 47 48 49 51 52 53 54 55 56 57 58 59 61 62 63 64 65 
#> 38 39 41 42 43 44 45 46 47 48 49 51 52 53 54 55 56 57 58 59 61 62 63 64 65 
#> 66 67 68 69 71 72 73 74 75 76 77 78 79 81 82 83 84 85 86 87 88 89 91 92 93 
#> 66 67 68 69 71 72 73 74 75 76 77 78 79 81 82 83 84 85 86 87 88 89 91 92 93 
#> 94 95 96 97 98 99 
#> 94 95 96 97 98 99
plot(bacias,
  # paleta de cores
  col = cores,
  horizontal = TRUE,
  breaks = bacias_id_brks, # lab.breaks = bacias_id,
  # lab.breaks = ifelse((1:length(bacias_id)) %% 2 == 0, "", bacias_id),
  axis.args = list( # at = bacias_id,
    #                   labels = ifelse(1:length(bacias_id) %% 2 == 0, " ", bacias_id),
    cex.axis = 0.5,
    las = 2
  ),
  legend.width = 1,
  legend.shrink = 1.1,
  # legend.mar = 2,
  legend.args = list(text = "Subbacia", side = 3)
)

Note que a barra de cores repete as cores para valores não existentes de códigos de subbacias (p.ex.: 20, 30, 40, …).

Opção 2: levelplot() do pacote rasterVis

Como uma alternativa podemos usar o pacote rasterVis. Entretanto algumas no raster original são necessárias: a conversão do raster para factor e a construção da tabela de atributos do novo raster.

# converte o raster para factor
bacias_f <- as.factor(bacias)
bacias_f
#> class       : RasterLayer 
#> dimensions  : 50, 89, 4450  (nrow, ncol, ncell)
#> resolution  : 1000, 1000  (x, y)
#> extent      : 1345500, 1434500, -887500, -837500  (xmin, xmax, ymin, ymax)
#> coord. ref. : NA 
#> data source : /home/hidrometeorologista/Downloads/basin2.asc 
#> names       : basin2 
#> values      : -2147483648, 2147483647  (min, max)
#> attributes  :
#>        ID
#>  from: 11
#>  to  : 99
# tabela de atributos raster com os níveis dos fatores
rat <- levels(bacias_f)[[1]]
rat$bacia <- as.character(bacias_id)
levels(bacias_f) <- rat
head(levels(bacias_f)[[1]])
#>   ID bacia
#> 1 11    11
#> 2 12    12
#> 3 13    13
#> 4 14    14
#> 5 15    15
#> 6 16    16
# plot das subbacias
rasterVis::levelplot(bacias_f,
  att = "bacia",
  col.regions = cores,
  # ver ?levelplot
  # para conhecer os parâmetros de colorkey
  colorkey = list(
    space = "bottom",
    labels = list(rot = 90, cex = 0.5)
  )
)

Opção 3: com ggplot() do pacote ggplot2

As funções do pacote ggplot2 trabalham com dados em dataframes. Então precisamos converter o raster para dataframe.

bacias_p <- as.data.frame(rasterToPoints(bacias))
head(bacias_p)
#>         x       y basin2
#> 1 1360000 -840000     18
#> 2 1362000 -840000     18
#> 3 1364000 -840000     18
#> 4 1365000 -840000     18
#> 5 1388000 -840000     44
#> 6 1389000 -840000     44

Vamos adaptar nossa paleta de cores atribuindo os códigos das subbacias a cada cor.

pal_cores <- cores
names(cores) <- as.character(bacias_id)
head(cores)
#>        11        12        13        14        15        16 
#> "#EDCBCB" "#72E5BB" "#DB7C97" "#639EC8" "#ADAD4F" "#5EE67E"

Plot das subbacias com o ggplot2.

ggp_subb <- ggplot(
  data = bacias_p,
  aes(x, y, fill = as.factor(basin2))
) +
  geom_raster() +
  scale_fill_manual("Subbacias", values = pal_cores) + theme_bw()
ggp_subb

Vamos adaptar a legenda, posicionando-a abaixo do gráfico, diminuindo o tamanho das quadrículas da legenda de cores.

ggp_subb +
  theme(legend.position = "bottom", legend.direction = "horizontal") +
  guides(fill = guide_legend(
    nrow = 4,
    byrow = TRUE,
    title.position = "top", title.hjust = 0.5,
    keywidth = 0.5, keyheight = 0.5
  ))

O resultado final do plot com o ggplot2 ficou visualmente melhor. As opções de customização do ggplot2 são amplas, o nome das funções e de seus argumentos são mais intuitivos, e a documentação é melhor para a visualização de dados espaciais categóricos.

Em geral, a melhor opção é aquela que o usuário domina ou que já usou previamente. Mas se você estiver começando, eu sugeriro usar o ggplot2.


  1. no Fedora Linux a biblioteca correspondente é a v8-314-devel.