J'ai des boîtes à moustaches sur highcharter et je voudrais personnaliser à la fois le
Voici mon code
df = data.frame(cbind(categ = rep(c('a','b','c','d')),value = rnorm(1000))) hcboxplot(var = df$categ, x = as.numeric(df$value)) %>% hc_chart(type = "column") %>% hc_colors(c("#203d7d","#a0a0ed","#203d7e","#a0a0ad"))
Les hc_colors ne fonctionnent que si je mets var2
au lieu de var code > mais alors les boîtes à moustaches sont rétrécies ...
3 Réponses :
Puisqu'il n'y a pas encore de réponse highcharter
, je vous donne au moins une solution de base.
Premièrement, votre définition du bloc de données est quelque peu imparfaite, faites plutôt:
boxplot(value ~ categ, dat, border=c("#203d7d","#a0a0ed","#203d7e","#a0a0ad"), pars=list(outpch=16))
À présent, utiliser boxplot
est assez simple. L'option border
colore vos bordures. Avec l'option col
, vous pouvez également colorer les remplissages.
dat <- data.frame(categ=c('a','b','c','d'), value=rnorm(1000))
Donne p >
API pour styliser fillColor : https: // api .highcharts.com / highcharts / series.boxplot.fillColor
Et pour "Couleur de la bordure" : https://api.highcharts.com/highcharts/series.boxplot.color
Exemple purement en JavaScript de style et de définition points: https://jsfiddle.net/BlackLabel/6tud3fgx
Et R code:
library(highcharter) df = data.frame(cbind(categ = rep(c('a','b','c','d', 'e')),value = rnorm(1000))) hcboxplot(var = df$categ, x = as.numeric(df$value)) %>% hc_chart(type = "column", events = list( load = JS("function() { var chart = this; chart.series[0].points[2].update({ color: 'red' }) chart.series[0].points[4].update({ x: 4, low: 600, q1: 700, median: 800, q3: 900, high: 1000, color: 'orange' }) }") )) %>% hc_plotOptions(boxplot = list( fillColor = '#F0F0E0', lineWidth = 2, medianColor = '#0C5DA5', medianWidth = 3, stemColor = '#A63400', stemDashStyle = 'dot', stemWidth = 1, whiskerColor = '#3D9200', whiskerLength = '20%', whiskerWidth = 3, color = 'black' )) %>% hc_colors(c("#203d7d","#a0a0ed","#203d7e","#a0a0ad"))
De mon côté j'ai en effet les couleurs personnalisées mais les mêmes pour chaque box.
Ma réponse n'est qu'un exemple. J'ai changé les couleurs pour des points spécifiques (points [2] et points [4]). Rien ne vous empêche de changer les couleurs de la série entière (chaque boîte) en utilisant chart.series [0] .update ({...})
J'ai créé quelques fonctions pour faire des trucs avec des highcharts et des boxplots. Il vous permettra de colorier chaque boîte à moustaches et de le remplir en conséquence, puis d'injecter de nouveaux paramètres graphiques selon l'API Highcharts, si vous le souhaitez.
Vérifiez-le:
library(highcharter) library(magrittr) library(viridisLite) df = data.frame(cbind(categ = rep(c('a','b','c','d')),value = rnorm(1000))) df$value<- base::as.numeric(df$value) add_variable_to_series_list<- function(x, series_list, key_vector, value_vector){ base::stopifnot(length(key_vector) == length(value_vector)) base::stopifnot(length(series_list) == length(key_vector)) series_list[[x]][length(series_list[[x]])+1]<- value_vector[x] names(series_list[[x]])[length(series_list[[x]])]<- key_vector[x] return(series_list[[x]]) } # From highcharter github pages: hc_add_series_bwpout = function(hc, value, by, ...) { z = lapply(levels(by), function(x) { bpstats = boxplot.stats(value[by == x])$stats outliers = c() for (y in na.exclude(value[by == x])) { if ((y < bpstats[1]) | (y > bpstats[5])) outliers = c(outliers, list(which(levels(by)==x)-1, y)) } outliers }) hc %>% hc_add_series(data = z, type="scatter", ...) } gen_key_vector<-function(variable, num_times){ return(rep(variable, num_times)) } gen_boxplot_series_from_df<- function(value, by,...){ value<- base::as.numeric(value) by<- base::as.factor(by) box_names<- levels(by) z=lapply(box_names, function(x) { boxplot.stats(value[by==x])$stats }) tmp<- lapply(seq_along(z), function(x){ var_name_list<- list(box_names[x]) #tmp0<- list(names(df)[x]) names(var_name_list)<- "name" index<- x-1 tmp<- list(c(index, z[[x]])) tmp<- list(tmp) names(tmp)<- "data" tmp_out<- c(var_name_list, tmp) #tmp<- list(tmp) return(tmp_out) }) return(tmp) } # Usage: #series<- gen_boxplot_series_from_df(value = df$total_value, by=df$asset_class) ## Boxplot function: make_highchart_boxplot_with_colored_factors<- function(value, by, chart_title="Boxplots", chart_x_axis_label="Values", show_outliers=FALSE, boxcolors=NULL, box_line_colors=NULL){ by<- as.factor(by) box_names_to_use<- levels(by) series<- gen_boxplot_series_from_df(value = value, by=by) if(is.null(boxcolors)){ cols<- viridisLite::viridis(n= length(series), alpha = 0.5) # Keeping alpha in here! (COLORS FOR BOXES ARE SET HERE) } else { cols<- boxcolors } if(is.null(box_line_colors)){ if(base::nchar(cols[[1]])==9){ cols2<- substr(cols, 0,7) # no alpha, pure hex truth, for box lines } else { cols2<- cols } } else { cols2<- box_line_colors } # Injecting value 'fillColor' into series list kv<- gen_key_vector(variable = "fillColor", length(series)) series2<- lapply(seq_along(series), function(x){ add_variable_to_series_list(x = x, series_list = series, key_vector = kv, value_vector = cols) }) if(show_outliers == TRUE){ hc<- highcharter::highchart() %>% highcharter::hc_chart(type="boxplot", inverted=FALSE) %>% highcharter::hc_title(text=chart_title) %>% highcharter::hc_legend(enabled=FALSE) %>% highcharter::hc_xAxis(type="category", categories=box_names_to_use, title=list(text=chart_x_axis_label)) %>% highcharter::hc_add_series_list(series2) %>% hc_add_series_bwpout(value = value, by=by, name="Outliers") %>% hc_plotOptions(series = list( marker = list( symbol = "circle" ), grouping=FALSE )) %>% highcharter::hc_colors(cols2) %>% highcharter::hc_exporting(enabled=TRUE) } else{ hc<- highcharter::highchart() %>% highcharter::hc_chart(type="boxplot", inverted=FALSE) %>% highcharter::hc_title(text=chart_title) %>% highcharter::hc_legend(enabled=FALSE) %>% highcharter::hc_xAxis(type="category", categories=box_names_to_use, title=list(text=chart_x_axis_label)) %>% highcharter::hc_add_series_list(series2) %>% hc_plotOptions(series = list( marker = list( symbol = "circle" ), grouping=FALSE )) %>% highcharter::hc_colors(cols2) %>% highcharter::hc_exporting(enabled=TRUE) } hc } # Usage: tst_box<- make_highchart_boxplot_with_colored_factors(value = df$value, by=df$categ, chart_title = "Some Title", chart_x_axis_label = "Some X Axis", show_outliers = TRUE) tst_box # Custom Colors: custom_colors_with_alpha_in_hex<- paste0(gplots::col2hex(sample(x=colors(), size = length(unique(df$categ)), replace = FALSE)), "80") tst_box2<- make_highchart_boxplot_with_colored_factors(value = df$value, by=df$categ, chart_title = "Some Title", chart_x_axis_label = "Some X Axis", show_outliers = TRUE, boxcolors = custom_colors_with_alpha_in_hex) tst_box2 tst_box3<- make_highchart_boxplot_with_colored_factors(value = df$value, by=df$categ, chart_title = "Some Title", chart_x_axis_label = "Some X Axis", show_outliers = TRUE, boxcolors = custom_colors_with_alpha_in_hex, box_line_colors = "black") tst_box3
Cela pourrait probablement être ajusté pour fonctionner avec un simple dataframe, mais je pense que cela vous donnera ce que vous voulez pour le moment sans avoir à le faire faire trop de travail supplémentaire. Aussi, peut-être regarder dans J'ai développé l'exemple pour qu'il fonctionne avec un DF standard. Selon certaines questions de suivi, les couleurs sont définies à l'aide de la palette Double Edit: Vous pouvez désormais spécifier un vecteur de couleurs pour chaque niveau de la variable factor list_parse
ou list_parse2 'de
highcharter ... cela pourrait probablement aider à construire l'objet
series`..Je toujours besoin d'examiner cela. p> p> e> Modifier: em> p> p> viridis
à l'intérieur de la fonction make_highchart_boxplot_with_colored_factors
. Si vous souhaitez autoriser votre propre palette et couleurs, vous pouvez exposer ces arguments et simplement les inclure en tant que paramètres dans l'appel de fonction. L'exemple développé emprunte comment ajouter des valeurs aberrantes à partir de la bibliothèque highcharter
(bien que de manière hacky), puis construit tout le reste à partir de zéro. J'espère que cela aidera à clarifier ma réponse précédente. Veuillez noter que je pourrais probablement aussi nettoyer la condition if
pour la rendre un peu plus brève, mais je l'ai gardée verbeuse à des fins d'illustration. ## Boxplots Data and names, note the data index (0,1,2) is the first number in the datum
series<- list(
list(
name="a",
data=list(c(0,1,2,3,4,5))
),
list(
name="b",
data=list(c(1,2,3,4,5,6))
),
list(
name="c",
data=list(c(2,3,4,5,6,7))
)
)
# Graphical attribute to be set: fillColor.
# Make the colors for the box fill and then also the box lines (make them match so it looks pretty)
cols<- viridisLite::viridis(n= length(series2), alpha = 0.5) # Keeping alpha in here! (for box fill)
cols2<- substr(cols, 0,7) # no alpha, pure hex truth, for box lines
gen_key_vector<-function(variable, num_times){
return(rep(variable, num_times))
}
kv<- gen_key_vector(variable = "fillColor", length(series))
# Make a function to put stuff in the 'series' list, requires seq_along to be used since x is the list/vector index tracker
add_variable_to_series_list<- function(x, series_list, key_vector, value_vector){
base::stopifnot(length(key_vector) == length(value_vector))
base::stopifnot(length(series_list) == length(key_vector))
series_list[[x]][length(series_list[[x]])+1]<- value_vector[x]
names(series_list[[x]])[length(series_list[[x]])]<- key_vector[x]
return(series_list[[x]])
}
## Put the extra stuff in the 'series' list
series2<- lapply(seq_along(series), function(x){ add_variable_to_series_list(x = x, series_list = series, key_vector = kv, value_vector = cols) })
hc<- highcharter::highchart() %>%
highcharter::hc_chart(type="boxplot", inverted=FALSE) %>%
highcharter::hc_title(text="This is a title") %>%
highcharter::hc_legend(enabled=FALSE) %>%
highcharter::hc_xAxis(type="category", categories=c("a", "b", "c"), title=list(text="Some x-axis title")) %>%
highcharter::hc_add_series_list(series2) %>%
hc_plotOptions(series = list(
marker = list(
symbol = "circle"
),
grouping=FALSE
)) %>%
highcharter::hc_colors(cols2) %>%
highcharter::hc_exporting(enabled=TRUE)
hc
J'ai ce que vous avez fait pour les couleurs de la bordure, mais je ne comprends pas vraiment comment changer la couleur de remplissage, j'ai tout rempli en noir lorsque je teste votre code
Avez-vous installé viridis?
Oui j'ai vérifié, il est installé, toujours rempli en noir :(
Même avec le code édité ? De plus, j'ai mal parlé quand j'ai dit d'installer virids
. J'aurais dû dire viridisLite
Semble fonctionner parfaitement maintenant, merci beaucoup!
Une seule chose ne fonctionne pas: la couleur des points aberrants
Ouais, c'est encore quelque chose sur lequel j'essaye de travailler. J'ai passé quelques heures à comprendre / expérimenter la manière de construire les données. Je suis devenu très proche, mais mes données finissent par être citées comme des caractères lorsque j'essaye d'ajouter différents ensembles de valeurs aberrantes. Je pense que c'est un problème avec la méthode toJSON
Je pense qu'elle est utilisée dans le package htmlwidgets
... toJSON
générera des éléments cités à partir d'une liste à moins qu'ils ne proviennent d'un dataframe
... Pour cette raison, j'obtiens quelque chose comme {data: [["2,10"], ["3,5"]]} code> lorsque j'essaie de convertir en JSON approprié. Voir ce JSFiddle: jsfiddle.net/BlackLabel/f2z9tLrs
Seriez-vous également ouvert à d'autres solutions que highcharter?
Dépend de la solution, je voudrais un tracé qui se dessine quand vous l'ouvrez comme dans highcharter. Je sais déjà comment le faire dans ggplot ou complotly.