Closed lucasmation closed 5 months ago
A chamada scale_color_ipea()
usa cores continuas como default discrete = F
.
se voce usar discrete = TRUE
vai funcionar.
iris |> ggplot(aes(Sepal.Length,Sepal.Width,color=as.factor(Petal.Width))) + geom_line() +
scale_color_ipea(discrete = TRUE) +
theme_ipea()
valeu. Mas este ajuste nao é uma coisa que o proprio "scale_color_ipea" nao deveria detectar automaticamente e adotar o padrao correto?
Me parece que nao tem como esperar que o usuario faça este grau de customizacao, etc... nao é o objetivo do pacote.
Você quer que o pacote detecte automaticamente se a variável da pessoa é discreta ou continua? @PedroJorge7 , é possivel implementar isso?
Dos pacotes que costumo usar, em geral eles pedem para o usuário informar se a variavel é continua ou discreta.
scale_color_viridis(discrete = TRUE)
scale_color_brewer()
e scale_fill_distiller()
para escalas continuasexato. Quando voce coloca: ggplot()+ geom_line() + theme_classic, por exemplo, ele vai la e muda as fontes, eixos, cores. Nao fica te perguntando que tipo de variaveis voce esta usando, etc... O ipeaplot deveria ser algo assim. Ja nao gosto de ter dois comandos suplementares (scale_color_ipea() + theme_ipea() ), mas tudo bem. Agora pelo menos que o usuario nao precise ficar especificando detalhes como o tipo de variavel...
No uso corrente do ggplot, as pessoas ja tem que passar chamadas diferentes, uma para cor outro para temas.
No theme_ipea()
funciona como um theme, tipo theme_classic()
, theme_bw()
. E veja que esses themes são utilizados para mudar a estetica da 'estrutura' do gráfico, mas não das cores dos dados representados nos graficos. Por isso se usa o scale_color_ipea()
seperado, seguindo o padrao do ggplot
Em relação ao pacote detectar automaticamente se a variável é discreta ou contínua nós passamos um bom tempo buscando uma solução como essa, mas não encontramos nenhum pacote que fizesse isso e nem uma solução.
O que eu tinha pensado inicialmente era tentar vincular pela classe da coluna (se for caractere, usaria discreto e se for numérico utiliza contínua), mas parece que há uma certa dificuldade de vincular os argumentos aes(color = ...)
com o scale_color_ipea.
Enfim, inicialmente me pareceu que era uma coisa bem interessante de se implementar, mas após várias tentativas acabamos deixando como argumento mesmo
Em relação a ideia de contemplar tudo dentro de um argumento só, o que tínhamos pensado foi o que o Rafa falou de manter o pacote dentro do padrão dos demais pacotes do R para evitar muita confusão.
Umas das primeiras versões do pacote até lembro que tinha essa opção de trabalhar com tudo junto, mas pensamos que fugir da usabilidade padrão talvez possa causar mais confusão do que ajudar.
@PedroJorge7 , @cavalcanti1985 ,
sobre esta dificuldade de automatizar a detecção do tipo de variavel Voces fizeram alguma pergunta no Stack Overflow sobre isso? Se ainda nao por favor façam a pergunta (bem feita ,reproduzível, mostrando a versão mais simplificada possível do código que reproduz o problema). E coloquem aqui para que possamos editar e upvote. Se mesmo assim ninguem no SO achar uma solucao eu aceito fechar o issue.
Certo. Seguindo sua sugestão, criamos essa pergunta no Stack Overflow
Muito bom. O problema da solucao do 'Allan Cameron' é que ela só funciona para plots basicos com uma unica camada, e os dados e aes
tem q ser passados no comando ggplot
e não no geom_
. Então seguindo a sugestão dele, por exemplo, isso aqui nao funciona:
ggplot() +
geom_point(data = mtcars, aes(x = mpg, y = hp, color = gear)) +
scale_color_ipea()
Provoquei ele no SO para ver se ele teria uma sugestao que cobre esses casos.
Pessoal. A partir da solução sugerida pelo Allan Cameron eu fiz novas modificações no nosso scale_color_ipea
. Antes de subir no github gostaria que vocês fizessem alguns testes para ver possíveis falhas da nova implementação. Caso alguma estrutura da função ou algum argumento não esteja fazendo sentido fiquem a vontade de sugerir mudanças.
# Definition of the scale_color_ipea function
scale_color_ipea <- function(discrete = F,
palette = c('Blue','Green','Orange','Pink','Green-Blue',
'Red-Blue','Green-Blue','Orange-Blue', 'Viridis',
'Inferno','Magma','Plasma','Cividis'),
palette_direction = 1,
decimal.mark = ",",
barheight = NULL, barwidth = NULL,
title.hjust = NULL, label.hjust = NULL,
...) {
structure(list(discrete = discrete, palette = palette, palette_direction = palette_direction,
decimal.mark = decimal.mark, barheight = barheight, barwidth = barwidth,
title.hjust = title.hjust, label.hjust = label.hjust,...), class = "scale_ipea")
}
# Definition of the ggplot_add.scale_ipea method
ggplot_add.scale_ipea <- function(object, plot, name, ...){
args <- object
discrete <- args$discrete
palette <- args$palette
palette_direction <- args$palette_direction
decimal.mark <- args$decimal.mark
barheight <- args$barheight
barwidth <- args$barwidth
title.hjust <- args$title.hjust
label.hjust <- args$label.hjust
# Set palette to 'ipea1' if it is not provided, otherwise use the provided value
palette <- ifelse(missing(palette),'Blue',palette)
if (decimal.mark == ",") {
# Use comma as decimal mark and dot as thousand separator for labels (Brazilian Portuguese)
labels = scales::label_comma(decimal.mark = ",", big.mark = ".")
} else if (decimal.mark == "."){
# Use dot as decimal mark and comma as thousand separator for labels (default)
labels = scales::label_comma(decimal.mark = ".", big.mark = ",")
} else {
stop("Decimal.mark argument must be '.' or ','.")
}
label.hjust = ifelse(is.null(label.hjust),0.5,label.hjust)
title.hjust = ifelse(is.null(title.hjust),0.5,title.hjust)
if(is.null(barheight)){
barheight = NULL
} else{
barheight = unit(barheight, units = "mm")
}
if(is.null(barwidth)){
barwidth = NULL
} else{
barwidth = unit(barwidth, units = "mm")
}
# Find the first layer with the defined 'color' aesthetic
for (i in seq_along(plot$layers)) {
if ("colour" %in% names(plot$layers[[i]]$mapping)) {
colour_var <- plot$layers[[i]]$mapping$colour
break
} else {
colour_var <- NULL
}
}
# If 'colour_var' was not found in any layer, check in the base ggplot call
if (is.null(colour_var) && !is.null(plot$mapping$colour)) {
colour_var <- plot$mapping$colour
}
# If 'colour_var' is not yet found, returns the graphic without changes
if (is.null(colour_var)) {
return(plot)
}
# Evaluates whether the variable is numeric.
# Based on this criterion, we will select whether the palette will be discrete or continuous.
var_evaluated <- rlang::eval_tidy(colour_var, plot$data)
auto_discrete_choose <- !is.numeric(var_evaluated)
!!!!!!!
# Acredito que em alguns casos (não vem nenhum em mente no momento) a seleção automática pode falhar.
# A ideia do tryCatch seria testar um 'plano B' que seria a estrutura já estabelecido no scale_color_ipea
# Caso vocês achem que não precisa do tryCatch, podemos remover o argumento 'discrete'
tryCatch({
# Choose the correct scale
if (auto_discrete_choose) {
return(plot +
list(ggplot2::discrete_scale(aesthetics = "color", scale_name = "ipea", ipea_pal(palette = palette, palette_direction = palette_direction), ...),
ggplot2::guides(colour = guide_legend(...))))
} else {
scale_manual_pal <- ipea_palette(palette = palette, n = 10, palette_direction = palette_direction)
return(
plot +
list(ggplot2::scale_color_gradientn(
labels = labels, # Set the labels for the gradient scale
colours = scale_manual_pal, # Set the scale_manual_pal for the gradient scale
...),
guides(color = guide_coloursteps(
label.hjust = label.hjust,
title.hjust = title.hjust,
barheight = barheight,
barwidth = barwidth,
title.position = 'top',
even.steps = F,...))))
}
}, error = function(e) {
!!!!!!!!!!!!!!
# Essa etapa daqui é uma sugestão, pois não tenho certeza se realmente seria necessário
# Plano B em caso de erro
if(isFALSE(discrete)){
# Set palette option
scale_manual_pal <- ipeaplot:::ipea_palette(palette = palette, n = 10, palette_direction = palette_direction)
# Graph
return(
plot +
list(ggplot2::scale_color_gradientn(
labels = labels, # Set the labels for the gradient scale
colours = scale_manual_pal, # Set the scale_manual_pal for the gradient scale
...),
guides(color = guide_coloursteps(
label.hjust = label.hjust,
title.hjust = title.hjust,
barheight = barheight,
barwidth = barwidth,
title.position = 'top',
even.steps = F,...)))
)
}
if(isTRUE(discrete)){
# Create a discrete color scale with the specified palette
return(
plot +
list(ggplot2::discrete_scale("color", "ipea", ipea_pal(palette = palette, palette_direction = palette_direction), ...),
ggplot2::guides(colour = guide_legend(...)))
)
}
})
}
Exemplos de uso
library(ggplot2)
library(ipeaplot)
ggplot(data = mtcars, aes(x = mpg, y = hp, color = as.character(gear))) +
geom_point() +
scale_color_ipea()
ggplot(data = mtcars, aes(x = mpg, y = hp, color = gear)) +
geom_point() +
scale_color_ipea()
ggplot(data = mtcars, aes(x = mpg, y = hp, color = as.character(gear))) +
geom_point() +
scale_color_ipea(palette = 'Red-Blue')
ggplot(data = mtcars, aes(x = mpg, y = hp, color = gear)) +
geom_point() +
scale_color_ipea(palette = 'Red-Blue')
ggplot(data = mtcars, aes(x = mpg, y = hp)) +
geom_point(aes(color = gear)) +
scale_color_ipea()
ggplot(data = mtcars, aes(x = mpg, y = hp)) +
geom_point(aes(color = as.character(gear))) +
scale_color_ipea()
ggplot(data = mtcars, aes(x = mpg, y = hp)) +
geom_point(aes(color = gear)) +
scale_color_ipea(palette = 'Magma')
ggplot(data = mtcars, aes(x = mpg, y = hp)) +
geom_point(aes(color = as.character(gear))) +
scale_color_ipea(palette = 'Magma')
ggplot(data = mtcars, aes(x = mpg, y = hp)) +
geom_point(aes(color = gear)) +
scale_color_ipea(palette = 'Viridis',barheight = 3, barwidth = 50) +
theme_ipea(legend.position = 'bottom')
Pessoal, boa noite! Conversei com o Pedro e como ele não encontrou nenhum problema na função então eu fiz a implementação da função no pacote. Quando puder gostaria que testassem para que assim a gente possa fechar o issue.
iris %>% ggplot(aes(Sepal.Length,Sepal.Width,color=as.factor(Petal.Width))) + geom_line() +
scale_color_ipea() +
theme_ipea()
@PedroJorge7 Testei por aqui e não encontrei nenhum problema até o momento. Vou deixar o issue aberto até o final da semana, se até lá não identificarmos nada, fecho, tudo bem?
Segue exemplo reproduzivel: