Este post foi editado em 06/02/2022.

História e outros blá blá blás…

Highsoft é o nome da empresa Norueguesa criadora da biblioteca Highchart. Segundo a própria empresa, a biblioteca é escrita puramente em JavaScript e é a mais popular do mundo (D3?).

A primeira versão da biblioteca data de 1995 e dentre alguns produtos interessantes da empresa está a edição de gráficos na nuvem (para não programadores). Quem quiser conferir é só acessar o endereço: https://cloud.highcharts.com/charts (não testado por esse que vos fala!).

O pacote em R serve “apenas” (não é simples criar uma casca para uma ferramenta tão poderosa) como uma casca para o uso da biblioteca original. Este pacote foi criado por esse cidadão chamado Joshua Kunst (aqui você pode conferir o blog do Joshua):

O pacote está na versão 0.5.0 0.9.4 (hoje: 16/03/2018 06/02/2022) e pode ser instalado apartir do comando:

install.packages("highcharter")

Para entender um pouco melhor do pacote sugiro a leitura da documentação do pacote e da página que descreve muitas funcionalidades. Para apreciar uma série de demos acesse a página de demonstração do highchart.

Antes de começarmos…

O perfeito entendimento do pacote depende da utilização do operador pipe (mentira, não é necessário. Mas fica mais legal!). O pipe (“%>%”) é um operador do pacote magrittr e permite a conexão de funções de uma forma bastante intuitiva. O grande ganho do uso deste operador está nos casos em que diversas operações são aplicadas sequencialmente em um determinado objeto.

Um operador nada mais é do que um função. Por exemplo, o operador soma (+) pode ser visto como um função:

2 + 2
## [1] 4
"+"(2, 2)
## [1] 4

Da mesma forma o operador “%>%” é uma função. Porém, com outros objetivos. Por exemplo, considere um programa cujo objetivo é gerar aleatoriamente um tamanho de amostra. Em seguida, gostaríamos de gerar uma amostra aleatória do tamanho antes sorteado e por fim calcular e mostrar a média do vetor. A seguir o código implementado na forma “convencional”:

set.seed(1)
tam <- sample(1:1000, size = 1)
amostra <- rnorm(tam)
media <- mean(amostra)
media
## [1] -0.01209849

A seguir o código implementado utilizando o operador pipe:

library(magrittr)
set.seed(1)
media <- sample(1:1000, size = 1) %>%
  rnorm() %>%
  mean() %>%
  print()
## [1] -0.01209849

Ou então um exemplo um pouco mais interessante…

library(dplyr)
mtcars %>% 
  select(mpg, carb, cyl, wt) %>%
  filter(cyl %in% c(4, 6, 8)) %>%
  group_by(cyl, carb) %>%
  summarise(mean_wt = mean(wt),
            mean_mpg = mean(mpg)) %>%
  arrange(desc(mean_wt))
## # A tibble: 9 × 4
## # Groups:   cyl [3]
##     cyl  carb mean_wt mean_mpg
##   <dbl> <dbl>   <dbl>    <dbl>
## 1     8     4    4.43     13.2
## 2     8     3    3.86     16.3
## 3     8     8    3.57     15  
## 4     8     2    3.56     17.2
## 5     6     1    3.34     19.8
## 6     6     4    3.09     19.8
## 7     6     6    2.77     19.7
## 8     4     2    2.40     25.9
## 9     4     1    2.15     27.6

Como pode ser visto, diversas operações foram realizadas operações de uma forma bastante intuitiva e lógica em cima da base mtcars. O resultado de cada operação entra como argumento para o próximo passo, não necessitando a criação de diversos objetos intermediários não úteis. Mais informações sobre o operador podem ser encontradas na documentação do magrittr.

É nítido que o pacote highcarter cria os gráficos em camadas. Um mesmo gráfico pode possuir diversos tipos de elementos tais como polígonos, linhas, pontos, barras, etc… A utilização desses elementos geram camadas e a composição das camadas gera um gráfico.

Por exemplo, podemos plotar o mapa do Brasil (camada 1: polígonos), na sequência podemos plotar pontos demarcando as cidade com mais de 1.000.000 de habitantes (camada 2: pontos). Numa terceira camada podemos ligar os pontos através de uma reta (camada 3: linhas) e por último é possível adicionar mais uma camada contendo um texto informando a distância entre os pontos (camada 4: texto).

A união das 4 camadas forma o gráfico. Para realizar a união das camadas gráficas o operador pipe (“%>%”“) será utilizado.

Mãos à obra

Primeiros passos: Gráficos simples

Os tipos mais comuns de gráficos são feitos utilizando os seguintes shortcuts:

  • hc_add_series: Linhas
  • hc_add_series + scatter: Dispersão
  • data_to_boxplot + hc_add_series_list: Boxplot
  • hchart: Histograma
  • hchart + pie: Setores
  • hchart + density: Densidade empírica
  • hchart + bar: Barras

Um aspecto interessante do pacote é a possibilidade de utilizar como input um data.frame e organizar os eixos, grupos e etc utilizando o argumento mapping como veremos nos gráficos abaixo. Este argumento funciona de forma equivalente ao argumento utilizado pelo pacote ggplot2. para um melhor entendimento consulte ?ggplot2::aes e ?highcharter::hcaes

Vejamos alguns exemplos:

Base geral para os exemplos:

dados <- data.frame(
  num1 = c(rnorm(25, mean = 0), rnorm(25, mean = 2), 
           rnorm(25, mean = 0), rnorm(25, mean = 2)), 
  num2 = c(rnorm(50, mean = 0), rnorm(50, mean = 2)),
  tamanho = rexp(100),
  grupo1 = rep(LETTERS[1:4], each = 25),
  grupo2 = rep(LETTERS[1:2], 50)
)

Em todos os codigos aparecerá o comando ‘frameWidget()’ porém ele só é necessário para apresentar o gráfico aqui na página. Para criar o gráfico na sua máquina esse comando não precisa ser utilizado.

Linhas:

highchart() %>%
  hc_add_series(
    data = dados, 
    mapping = hcaes(y = num1), 
    type = "line"
  ) %>%
  frameWidget()
highchart() %>%
  hc_add_series(
    data = dados, 
    mapping = hcaes(y = num1, group = grupo1), 
    type = "line"
  ) %>%
  frameWidget()



Dispersão:

highchart() %>%
  hc_add_series(
    data = dados,
    mapping = hcaes(x = num1, y = num2),
    type = "scatter"
  ) %>%
  frameWidget()
highchart() %>%
  hc_add_series(
    data = dados,
    mapping = hcaes(
      x = num1, 
      y = num2, 
      size = tamanho
    ),
    type = "scatter"
  ) %>%
  frameWidget()
highchart() %>%
  hc_add_series(
    data = dados,
    mapping = hcaes(
      x = num1, 
      y = num2, 
      size = tamanho, group = grupo1
    ),
    type = "scatter"
  ) %>%
  frameWidget()



Boxplot:

dat <- data_to_boxplot(data = dados, variable = num1)
highchart() %>%
  hc_add_series_list(dat) %>%
  frameWidget()
dat <- data_to_boxplot(data = dados, variable = num1, group_var = grupo1)
highchart() %>%
  hc_add_series_list(dat) %>%
  frameWidget()
dat <- data_to_boxplot(data = dados, variable = num1, group_var = grupo1, group_var2 = grupo2)
highchart() %>%
  hc_add_series_list(dat) %>%
  frameWidget()



Histograma:

hchart(object = dados$num1) %>%
  frameWidget()



Setores:

dat <- dados %>% group_by(grupo1) %>% summarise(n = n())
hchart(
  object = dat, 
  type = "pie", 
  mapping = hcaes(name = grupo1,y = n)
) %>%
  frameWidget()



Densidade empírica:

hchart(object = density(dados$num2)) %>%
  frameWidget()



Barras:

hchart(object = as.character(rpois(50, lambda = 2)), type = "bar") %>%
  frameWidget()

Customizando gráficos e adicionando temas

Apesar dos gráficos já estarem visualmente agradáveis, por diversas vezes sentimos a necessidade de customizar alguns aspectos, por exemplo, cor da linha, tamanho da linha, tamanho do texto, legenda dos eixos, etc…

A seguir apresento o gráfico de linhas e algumas customizações pertinentes: cor, tamanho da linha e nome na legenda:

highchart() %>%
  hc_add_series(
    name = "Nome da série na legenda",
    data = dados,
    mapping = hcaes(y = num1),
    type = "line",
    lineColor = "#db4716", 
    lineWidth = 4
  ) %>%
  frameWidget()



Customizações similares podem ser feitas nos demais gráficos.

highchart() %>%
  hc_add_series(
    name = "Nome da série na legenda",
    data = dados,
    mapping = hcaes(x = num1, y = num2),
    marker = list(
      radius = 10,
      symbol = "diamond",
      lineColor = "IndianRed",
      lineWidth = 3
    ),
    color = "steelblue",
    type = "scatter"
  ) %>%
  frameWidget()

Outros parâmetros gráficos podem ser alterados com o uso da função hc_chart. As customizações possíveis são as encontradas na página de opções do highchart. Por exemplo (desprezando a aparência):

highchart() %>%
  hc_add_series(
    name = "Nome da série na legenda",
    data = dados,
    mapping = hcaes(x = num1, y = num2),
    marker = list(
      radius = 10,
      symbol = "diamond",
      lineColor = "IndianRed",
      lineWidth = 3
    ),
    color = "steelblue",
    type = "scatter"
  ) %>%
  hc_chart(
    backgroundColor = "blue",
    borderColor = "red",
    borderWidth = 5,
    selectionMarkerFill = "black"
  ) %>%
  frameWidget()



Em que:

  • radius: Tamanho do ponto
  • lineColor: Cor da linha dos pontos
  • lineWidth: Tamanho da linha dos pontos
  • color: Cor do ponto
  • backgroundColor: Cor de fundo
  • borderColor: Cor da borda do gráfico
  • borderWidth: Tamanho da borda do gráfico
  • selectionMarkerFill: Cor do texto da legenda quando selecinado pelo mouse (o clique faz com que o grupo selecionado desapareça)

A seguir a lista de opções de customização de alguns tipos de gráficos já vistos:

Esses argumentos já nos dão uma boa liberdade na hora de criar um gráfico.

highchart() %>%
  hc_add_series(
    data = dados,
    mapping = hcaes(
      x = num1, y = num2,
      group = grupo1
    ),
    marker = list(radius = 1, symbol = "circle"),
    type = "scatter"
  ) %>%
  hc_chart(
    backgroundColor = "black",
    borderColor = "white",
    borderWidth = 5,
    selectionMarkerFill = "white"
  ) %>%
  hc_yAxis(
    gridLineColor = grey(0.1),
    gridLineWidth = 2.5
  ) %>%
  hc_colors(colors = c("SteelBlue", "IndianRed", "SeaGreen", grey(0.9))) %>%
  frameWidget()



Porém customizar um gráfico não é uma tarefa simples e exige bastante estudo. Por sorte este pacote conta com diversos temas gráficos prontos (alguém já investiu algum tempo estudando cores, formas, tamanhos, etc…). Estes temas podem ser utilizados com o comando hc_add_theme.

highchart() %>%
  hc_add_series(
    data = dados,
    mapping = hcaes(
      x = num1, y = num2,
      group = grupo1
    ),
    type = "scatter") %>%
  hc_add_theme(hc_thm = hc_theme_monokai()) %>%
  frameWidget()



Alguns temas disponíveis:

  • darkunica
  • economist
  • sparkline
  • monokai

O mais interessante é que podemos criar nosso próprio tema e com isso padronizar nossos gráficos (cores, tamanhos de linhas e pontos, fonte, legenda, etc…). Por exemplo:

s4g_tema <- hc_theme(
  colors = c('#003E57', '#0699C7', '#F2F2F2', '#F24405', '#A6351C'),
  chart = list(
    backgroundColor = NULL,
    divBackgroundImage = "https://wallpaperbrowse.com/media/images/background-7.jpg"
  ),
  legend = list(
    itemStyle = list(
      fontFamily = 'Comic Sams',
      fontSize = 15,
      color = 'navy'
    ),
    itemHoverStyle = list(
      color = 'red'
    )   
  )
)

highchart() %>%
  hc_add_series(
    data = dados,
    mapping = hcaes(
      x = num1, y = num2,
      group = grupo1
    ),
    marker = list(radius = 4, symbol = "circle"),
    type = "scatter"
  ) %>%
  hc_add_theme(hc_thm = s4g_tema) %>%
  frameWidget()



Obviamente hora ou outra surgirão necessidades que não estão exemplificadas neste material. Nestes casos o Google dá conta!

Combinando gráficos

Como fazemos para combinar gráficos? Simples…

x = seq(-5, 5, length.out = 1000)
dens_norm <- data.frame(x = x, y = dnorm(x = x))
dados_norm <- data.frame(x = rnorm(1000))

hchart(name = "Histograma", object = dados_norm$x) %>% 
  hc_add_series(
    name = "Densidade teórica", 
    data = dens_norm, 
    mapping = hcaes(x = x, y = y),
    color = "IndianRed",
    lineWidth = 3,
    type = "line",
    yAxis = 1
  ) %>%
  hc_add_series(
    name = "Dados",
    data = dados_norm, 
    mapping = hcaes(x = x, y = 0),
    color = "seagreen",
    type = "scatter"
  ) %>%
  hc_yAxis_multiples(
    list(
      title = list(text = "Histograma"),
      align = "left",
      showFirstLabel = FALSE,
      showLastLabel = FALSE
    ),
    list(
      title = list(text = "Densidade"),
      align = "right",
      showFirstLabel = FALSE,
      showLastLabel = FALSE,
      opposite = TRUE
    )
  ) %>%
  frameWidget()

O highchart nada mais é do que uma combinação de camadas, portanto, basta adicionarmos camadas aos gráficos!

Função hchart

A função hchart é capaz de transformar diversas classes de objetos em gráficos. Desta forma, podemos utilizar diretamente uma saída do R e executar o seu respectivo gráfico:

x <- acf(diff(AirPassengers), plot = FALSE)
plot(x)

hchart(x) %>%
  frameWidget()



As classes suportadas pela função são:

methods(hchart)
##  [1] hchart.acf*        hchart.character*  hchart.data.frame* hchart.default*   
##  [5] hchart.density*    hchart.dist*       hchart.ets*        hchart.factor*    
##  [9] hchart.forecast*   hchart.histogram*  hchart.igraph*     hchart.list*      
## [13] hchart.matrix*     hchart.mforecast*  hchart.mts*        hchart.numeric*   
## [17] hchart.prcomp*     hchart.princomp*   hchart.stl*        hchart.survfit*   
## [21] hchart.tibble*     hchart.ts*         hchart.xts*       
## see '?methods' for accessing help and source code

Gráficos mais interessantes

A disseminação de informação por meio de gráficos é uma tarefa difícil. Devemos nos atentar aos aspectos visuais tais como cores e formas e além disso precisamos apresentar informações de uma maneira concisa e clara. Pensando nisso diversos pesquisadores investem seu tempo na criação de formas de se visualizar dados que fogem do convencional que acabamos de ver.

Base de dados:

Utilizaremos dados referentes a características dos Pokémons.

data(pokemon)
head(pokemon)
## # A tibble: 6 × 24
##      id pokemon    species_id height weight base_experience type_1 type_2 attack
##   <dbl> <chr>           <dbl>  <dbl>  <dbl>           <dbl> <chr>  <chr>   <dbl>
## 1     1 Bulbasaur           1      7     69              64 grass  poison     49
## 2     2 Ivysaur             2     10    130             142 grass  poison     62
## 3     3 Venusaur            3     20   1000             236 grass  poison     82
## 4     4 Charmander          4      6     85              62 fire   <NA>       52
## 5     5 Charmeleon          5     11    190             142 fire   <NA>       64
## 6     6 Charizard           6     17    905             240 fire   flying     84
## # … with 15 more variables: defense <dbl>, hp <dbl>, special_attack <dbl>,
## #   special_defense <dbl>, speed <dbl>, type_1_color <chr>, type_2_color <chr>,
## #   type_mix_color <chr>, egg_group_1 <chr>, egg_group_2 <chr>, color <chr>,
## #   detail_url <chr>, image_url <chr>, image_alt_urls <list>, icon_url <chr>

A partir de agora iremos aprender a criar os seguintes gráficos:

  • Column range
  • Polar chart
  • Pirâmides
  • Heatmaps
  • Treemaps
  • Mapas

Column range:

dados2 <- pokemon %>%
  group_by(type_1) %>%
  summarise(
    min = min(hp),
    max = max(hp),
    velocidade = mean(speed, na.rm = T)
  )

highchart() %>%
  hc_add_series(
    name = "Hp",
    data = dados2, 
    mapping = hcaes(
      x = type_1, 
      low = min, high = max, 
      color = velocidade
    ),
    type = "columnrange"
  ) %>%
  frameWidget()

Polar chart:

highchart() %>%
  hc_add_series(
    name = "Hp dos Pokémons",
    data = dados2, 
    mapping = hcaes(
      x = type_1, 
      low = min, high = max, 
      color = velocidade
    ),
    type = "columnrange"
  ) %>%
  hc_chart(polar = T) %>%
  frameWidget()
library(reshape2)
dados3 <- pokemon %>%
  group_by(type_1) %>%
  summarise(
    ataque = mean(attack, na.rm = T),
    defesa = mean(defense, na.rm = T)
  ) %>%
  arrange(ataque) %>%
  melt(
    id.vars = 1, 
    variable.name = "caracteristica", 
    value.name = "media"
  )

highchart() %>%
  hc_add_series(
    data = dados3, 
    mapping = hcaes(
      y = media, 
      name = type_1,
      group = caracteristica
    ),
    type = "line"
  ) %>%
  hc_chart(polar = T) %>%
  hc_colors(colors = c("IndianRed", "SteelBlue")) %>%
  frameWidget()

Pirâmides:

dados4 <- pokemon %>%
  group_by(type_1) %>%
  summarise(n = length(id)) %>%
  arrange(n)

highchart() %>%
  hc_add_series(
    name = "Número de Pokémons",
    data = dados4, 
    mapping = hcaes(y = n, name = type_1), 
    type = "pyramid"
  ) %>%
  frameWidget()

Matriz de distâncias:

dados5 <- pokemon %>%
  select(
    pokemon, type_1,
    height, weight, 
    base_experience, 
    attack, defense, 
    hp, speed,
    special_attack, special_defense
  ) %>%
  as.data.frame() %>%
  sample_n(size = 50) %>%
  arrange(type_1)
row.names(dados5) <- dados5$pokemon
head(dados5)
##               pokemon type_1 height weight base_experience attack defense hp
## Kakuna         Kakuna    bug      6    100              72     25      50 45
## Pheromosa   Pheromosa    bug     18    250             257    137      37 71
## Golisopod   Golisopod    bug     20   1080             186    125     140 75
## Forretress Forretress    bug     12   1258             163     90     140 75
## Shuckle       Shuckle    bug      6    205             177     10     230 20
## Accelgor     Accelgor    bug      8    253             173     70      40 80
##            speed special_attack special_defense
## Kakuna        35             25              25
## Pheromosa    151            137              37
## Golisopod     40             60              90
## Forretress    40             60              60
## Shuckle        5             10             230
## Accelgor     145            100              60
hchart(dist(scale(dados5[,-c(1,2)]))) %>%
  frameWidget()

Heatmap:

anos <- 5

dados6 <- expand.grid(seq(12) - 1, seq(anos) - 1)
dados6$valor <- abs(seq(nrow(dados6)) + 10 * rnorm(nrow(dados6))) + 10
dados6$valor <- round(dados6$valor, 2)

highchart() %>% 
  hc_xAxis(categories = month.abb) %>% 
  hc_yAxis(categories = 2016 - anos + seq(anos)) %>% 
  hc_add_series(
    data = dados6, 
    name = "Valor observado",
    mapping = hcaes(
      x = Var1, 
      y = Var2, 
      value = valor
    ), 
    type = "heatmap"
  ) %>%
  hc_colorAxis(minColor = "#FFFFFF", maxColor = "#434348") %>%
  frameWidget()

Treemap:

highchart() %>% 
  hc_add_series(
    data = dados4, 
    mapping = hcaes(name = type_1, value = n),
    type = "treemap", colorByPoint = TRUE
  )  %>%
  frameWidget()

Mapas:

mapdata <- get_data_from_map(download_map_data("countries/br/br-all"))

dados_falsos <- mapdata %>% 
  select(code = `hc-a2`) %>% 
  mutate(taxa = round(rbeta(n = nrow(.), shape1 = 1, shape2 = 1), 2))

dclass <- tibble(
  from = seq(0, 0.9, by = 0.1),
  to = seq(0.1, 1, by = 0.1),
  color = colorRampPalette(
    colors = c("SteelBlue","IndianRed"))(length(from))
)
dclass <- list_parse(dclass)

hcmap("countries/br/br-all", data = dados_falsos,
      name = "Estado",
      value = "taxa", joinBy = c("hc-a2", "code")) %>%
  hc_colorAxis(dataClasses = dclass) %>%
  frameWidget()

Novamente existem diversas customizações cabíveis. Algumas delas podem ser encontradas nos seguintes links:

Alguns exemplos

Agora já conhecemos várias funções e algumas formas de se customizar um gráfico. Então, vamos por o que aprendemos em prática. Para isso vamos tentar explorar a base de dados pokemons.

Antes de mais nada vamos padronizar os gráficos criando um tema:

poke_tema <- hc_theme_merge(
  hc_theme_darkunica(),
  hc_theme(
    chart = list(
      backgroundColor = 'transparent'
    ),
    legend = list(
      itemStyle = list(
        fontSize = 14,
        fontFamily = "Roboto",
        color = 'white'
      ),
      itemHoverStyle = list(
        color = '#2062ac'
      )   
    )
  )
)

Vejamos como se distribuem as classes secundárias dentro das classes primárias de Pokémons.

library(treemap)
Classes <- pokemon %>%
  group_by(type_1, type_2) %>%
  summarise(n = as.numeric(length(id)),
            cor = first(type_1_color),
            cor1 = first(type_2_color)) %>%
  ungroup() %>%
  mutate(type_2 = factor(ifelse(is.na(type_2), paste("only", type_1), type_2))) %>%
  mutate(type_1 = factor(type_1)) %>%
  as.data.frame() 

tm <- treemap(Classes, index = c("type_1", "type_2"),
              vSize = "n", vColor = "type_1", draw = F)
tm$tm <- tm$tm %>%
  left_join(Classes %>% select(type_1, type_2, cor) %>% distinct(), by = c("type_1", "type_2")) %>%
  left_join(Classes %>% select(type_1, cor1) %>% distinct(), by = c("type_1")) %>%
  mutate(type_1 = paste0("Tipo:", type_1),
         color = ifelse(is.na(cor), cor1, cor))

# 06/02/2022 - https://jkunst.com/highcharter/articles/showcase.html
cols <- tm$tm %>% 
  count(type_1, type_2, color, sort = TRUE) %>% 
  pull(color) %>% 
  unique()

dat <- data_to_hierarchical(data = tm$tm, group_vars = c(type_1, type_2), size_var = vSize, colors = cols)

hchart(object = dat, type = "treemap") %>%
  frameWidget()



Podemos também comparar as forças de alguns Pokémons (selecione alguns para compará-los):

pokemons <- c("Pikachu", "Blastoise", "Snorlax", "Psyduck",
              "Alakazam", "Articuno", "Lugia", "Mewtwo", 
              "Mr-mime" ,"Ditto")
Forca_poke <- pokemon %>%
  filter(pokemon %in% pokemons) %>%
  select(pokemon, 
         attack, defense, 
         speed, hp, 
         special_attack, special_defense,
         type_1_color) %>%
  melt(id.vars = c("pokemon", "type_1_color"), variable.name = "caracteristica", value.name = "valor")

poke_tema_forca <- hc_theme_merge(
  poke_tema,
  hc_theme(
    chart = list(
      divBackgroundImage = 'https://cdn.wallpapersafari.com/76/86/OgDyiP.jpg'
    )
  )
)

highchart(height = 500, width = 670) %>%
  hc_add_series(
    data = Forca_poke, 
    mapping = hcaes(
      y = valor, 
      name = caracteristica,
      group = pokemon
    ),
    marker = list(symbol = "circle"),
    type = "line") %>%
  hc_chart(polar = T) %>% 
  hc_xAxis(
    categories = c(
      "Ataque", "Defesa", "Velocidade", 
      "Hit points", "Ataque especial", 
      "Defesa especial"
    )
  ) %>%
  hc_tooltip(
    backgroundColor = grey(0.2),
    borderRadius = 0,
    borderWidth = 5
  ) %>%
  hc_add_theme(poke_tema_forca) %>%
  frameWidget()



poke_tema_donnut <- hc_theme_merge(
  poke_tema,
  hc_theme(
    chart = list(
      backgroundColor = grey(0.1)
    )
  )
)

pokemons <- c("Lugia", "Mewtwo")

poke_poder <- pokemon %>%
  filter(pokemon %in% pokemons) %>%
  select(
    pokemon, 
    attack, defense, 
    special_attack, 
    special_defense
  ) %>%
  melt(id.vars = "pokemon", variable.name = "caracteristica", value.name = "valor") %>%
  dcast(formula = caracteristica ~ pokemon, fun.aggregate = sum, value.var = "valor") 

cat_names <- data.frame(
  ingles = c("attack", "defense", "special_attack", "special_defense"),
  portugues = c("Ataque", "Defesa", "Ataque especial", "Defesa especial")
)

poke_poder <- merge(poke_poder, cat_names, by.x = "caracteristica", by.y= "ingles")

lugia <- highchart(width = 350, height = 300) %>%
  hc_add_series(
    data = poke_poder, 
    mapping = hcaes(
      x = portugues, 
      y = Lugia
    ),
    name = "Lugia",
    type = "pie", 
    size = '65%', innerSize = "60%"
  ) %>%
  hc_xAxis(categories = poke_poder$Lugia) %>%
  hc_tooltip(
    backgroundColor = grey(0.2),
    borderRadius = 0,
    borderWidth = 5
  ) %>%
  hc_add_theme(poke_tema_donnut) %>%
  hc_title(text = "Lugia", verticalAlign = "middle")

mewtwo <- highchart(width = 350, height = 300) %>%
  hc_add_series(
    data = poke_poder, 
    mapping = hcaes(
      x = portugues, 
      y = Mewtwo
    ),
    name = "Mewtwo",
    type = "pie", 
    size = '65%', innerSize = "60%") %>%
  hc_xAxis(categories = poke_poder$mewtwo) %>%
  hc_tooltip(
    backgroundColor = grey(0.2),
    borderRadius = 0,
    borderWidth = 5
  ) %>%
  hc_add_theme(poke_tema_donnut) %>%
  hc_title(text = "Mewtwo", verticalAlign = "middle")
lugia %>% frameWidget()
mewtwo %>% frameWidget()



Ou então investigar quais são os pokémons com maior IMC e observar níveis de defesa e de ataque:

poke_tema_imc <- hc_theme_merge(
  poke_tema,
  hc_theme(
    chart = list(
      divBackgroundImage = 'https://s-media-cache-ak0.pinimg.com/originals/15/39/eb/1539eb20b1d14f6c789226386aedde41.jpg'
    )
  )
)

IMC_poke <- pokemon %>%
  mutate(
    weight = weight/10,
    height = height*10
  ) %>%
  mutate(IMC = round(weight/(height/100)^2, 2)) %>%
  mutate(
    IMC_cat = cut(
      x = IMC,
      breaks = c(0, 16, 17, 18.5, 25, 30, 35, 40, 1000),
      labels = c(
        "Magreza grave", 
        "Magreza moderada", 
        "Magreza leve", 
        "Saudável", 
        "Sobrepeso", 
        "Obesidade grau I", 
        "Obesidade grau II (severa)", 
        "Obesidade grau III (mórbida)"
      )
    )
  )

library(shiny)
library(purrr)
library(stringr)
urlimage <- "https://raw.githubusercontent.com/phalt/pokeapi/master/data/Pokemon_XY_Sprites/"

tooltip <- list(
  c("pokemon", "Pokémon"),
  c("type_1", "Tipo principal"), 
  c("type_2", "Tipo secundário"),
  c("weight", "Peso"),
  c("height", "Altura"),
  c("speed", "Velocidade"),
  c("hp", "Pontos de vida"),
  c("attack", "Ataque"),
  c("defense", "Defesa"),
  c("special_attack", "Ataque epecial"),
  c("special_defense", "Defesa especial"),
  c("IMC", "IMC")
) %>%
  map(function(x){
    tags$tr(
      tags$th(str_replace_all(str_to_title(x[2]), "_", " ")),
      tags$td(paste0("{point.", x[1], "}"))
    )
  }) %>%
  do.call(tagList, .) %>% 
  tagList(
    tags$img(
      src = paste0(urlimage, paste0("{point.id}", ".png")),
      width = "125px", height = "125px"
    )
  ) %>%
  as.character()

highchart(height = 500, width = 800) %>%
  hc_add_series(
    data = IMC_poke, 
    mapping = hcaes(
      x = attack, y = defense, 
      group = IMC_cat,
      name = IMC_cat
    ), 
    type = "scatter",
    marker = list(radius = 5, symbol = "circle")
  ) %>%
  hc_tooltip(
    backgroundColor = grey(0.2),
    useHTML = TRUE,
    borderRadius = 0,
    borderWidth = 5,
    headerFormat = "<table>",
    pointFormat = tooltip,
    footerFormat = "</table>"
  ) %>%
  hc_yAxis(title = list(text = "Defesa"), min = 0) %>%
  hc_xAxis(title = list(text = "Ataque"), min = 0) %>%
  hc_add_theme(hc_thm = poke_tema_imc) %>%
  hc_credits(
    enabled = TRUE, text = "Source: wallpaper safari",
    href = "https://wallpapersafari.com/fan-art-wallpapers/"
  ) %>%
  frameWidget()



Aparentemente o IMC humano não é interessante para avaliar peso e altura de Pokémons “/