Как заполнить гистограмму цветовым градиентом?

У меня простая проблема. Как построить гистограмму с ggplot2 с фиксированным binwidth и заполненную цветами радуги (или любой другой палитрой)?

Допустим, у меня есть такие данные:

myData <- abs(rnorm(1000))

Я хочу построить гистограмму, используя, например. binwidth=.1. Это, однако, вызовет разное количество бинов, в зависимости от данных:

ggplot() + geom_histogram(aes(x = myData), binwidth=.1) 

введите описание изображения здесь

Если бы я знал количество ячеек (например, n=15), я бы использовал что-то вроде:

ggplot() + geom_histogram(aes(x = myData), binwidth=.1, fill=rainbow(n))

Но с изменением количества бункеров я как бы застрял на этой простой проблеме.


person Art    schedule 27.10.2016    source источник
comment
Итак, если я вас правильно понял, вы хотите, чтобы каждый бин гистограммы был окрашен по-разному в соответствии с радужным градиентом?   -  person sebastian-c    schedule 27.10.2016
comment
Да, это именно то, что я хочу   -  person Art    schedule 27.10.2016
comment
@user20650 user20650 Я видел этот ответ, но там фиксированное количество корзин, так что это не решает мою проблему.   -  person Art    schedule 27.10.2016
comment
@yup согласился...   -  person user20650    schedule 27.10.2016
comment
Почему бы просто не указать количество бинов через аргумент bins?   -  person Roman Luštrik    schedule 27.10.2016
comment
@RomanLuštrik: Потому что мне нужна фиксированная ширина корзины, а не фиксированное количество корзин. Если бы я мог это сделать, я бы не спрашивал :)   -  person Art    schedule 27.10.2016
comment
Кажется, это работает... n <- round(((max(myData)-min(myData))/.1)+1)   -  person Rupert    schedule 27.10.2016


Ответы (2)


Если вы действительно хотите, чтобы количество бинов было гибким, вот мой небольшой обходной путь:

library(ggplot2)

gg_b <- ggplot_build(
  ggplot() + geom_histogram(aes(x = myData), binwidth=.1)
)

nu_bins <- dim(gg_b$data[[1]])[1]

ggplot() + geom_histogram(aes(x = myData), binwidth=.1, fill = rainbow(nu_bins))

введите описание изображения здесь

person J_F    schedule 27.10.2016
comment
Ага, это именно то, что мне нужно. Я просто думал (и надеялся), что есть более простой способ сделать это :) Спасибо! - person Art; 27.10.2016

В случае, если ширина бина фиксирована, вот альтернативное решение, которое использует внутреннюю функцию ggplot2:::bin_breaks_width() для получения количества бинов перед созданием графика. Это все еще обходной путь, но он позволяет избежать двойного вызова geom_histogram(), как в другом решении:

# create sample data
set.seed(1L)
myData <- abs(rnorm(1000))
binwidth <- 0.1

# create plot    
library(ggplot2)   # CRAN version 2.2.1 used
n_bins <- length(ggplot2:::bin_breaks_width(range(myData), width = binwidth)$breaks) - 1L
ggplot() + geom_histogram(aes(x = myData), binwidth = binwidth, fill = rainbow(n_bins)) 

введите здесь описание изображения


В качестве третьего варианта агрегирование может выполняться за пределами ggplot2. Тогда вместо geom_histogram() можно использовать geom_col():

# start binning on multiple of binwidth
start_bin <- binwidth * floor(min(myData) / binwidth)
# compute breaks and bin the data
breaks <- seq(start_bin, max(myData) + binwidth, by = binwidth)
myData2 <- cut(sort(myData), breaks = breaks, by = binwidth)

ggplot() + geom_col(aes(x = head(breaks, -1L), 
                        y = as.integer(table(myData2)), 
                        fill = levels(myData2))) + 
  ylab("count") + xlab("myData")

введите здесь описание изображения

Обратите внимание, что breaks откладывается по оси x вместо levels(myData2), чтобы ось x оставалась непрерывной. В противном случае каждая метка фактора будет нанесена на график, что приведет к загромождению оси x. Также обратите внимание, что вместо rainbow() используется встроенная цветовая палитра ggplot2.

person Uwe    schedule 16.06.2017