Графическая карта вероятности/гексбин с разным размером бункеров

Это связано с другим вопросом: взвешенная по частоте матрица.

У меня есть эта графика (созданная кодом ниже в R): multisample

#Set the number of bets and number of trials and % lines
numbet <- 36 
numtri <- 1000 
#Fill a matrix where the rows are the cumulative bets and the columns are the trials
xcum <- matrix(NA, nrow=numbet, ncol=numtri)
for (i in 1:numtri) {
x <- sample(c(0,1), numbet, prob=c(5/6,1/6), replace = TRUE)
xcum[,i] <- cumsum(x)/(1:numbet)
}
#Plot the trials as transparent lines so you can see the build up
matplot(xcum, type="l", xlab="Number of Trials", ylab="Relative Frequency", main="", col=rgb(0.01, 0.01, 0.01, 0.02), las=1)

Мне очень нравится, как этот сюжет строится и показывает более частые пути, такие же темные, чем более редкие пути (но это недостаточно ясно для презентации печати). То, что я хотел бы сделать, это создать какой-то гексбин или тепловую карту для чисел. Подумав об этом, кажется, что сюжет должен будет включать в себя различные бункеры (см. Мою эскиз огибающей):

binsketch

Мой вопрос: Если я смоделирую миллион прогонов, используя вышеприведенный код, как я могу представить его как тепловую карту или гексбин, с различными ячейками, как показано на эскизе?

Чтобы уточнить: я не хочу полагаться на прозрачность, чтобы показать редкость судебного разбирательства, проходящего через часть сюжета. Вместо этого я хотел бы обозначить редкость с теплом и показать общий путь как горячий (красный) и редкий путь как холодный (синий). Кроме того, я не думаю, что ящики должны быть одного размера, потому что первое испытание имеет только два места, где может быть путь, но в последнем есть еще много. Отсюда и тот факт, что я выбрал меняющуюся шкалу бинов, основанную на этом факте. По сути, я подсчитываю количество раз, когда путь проходит через ячейку (2 в столбце 1, 3 в столбце 2 и т.д.), а затем окрашивает ячейку в зависимости от того, сколько раз она прошла.

ОБНОВЛЕНИЕ: У меня уже был сюжет, похожий на @Andrie, но я не уверен, что он намного яснее, чем верхний сюжет. Это разрывный характер этого графика, который мне не нравится (и почему я хочу какую-то тепловую карту). Я думаю, что, поскольку в первом столбце есть только два возможных значения, не должно быть огромного визуального разрыва между ними и т.д. Поэтому я предполагал, что ящики разных размеров. Я все еще чувствую, что версия binning будет показывать большее количество образцов.

plot2

Обновление: Этот веб-сайт описывает процедуру построения карты тепла:

Чтобы создать версию графика плотности (Heatmap), мы должны эффективно перечислять появление этих точек в каждом дискретном месте на изображении. Это делается путем установки сетки и подсчета количества раз, когда координата точки "падает" в каждый из отдельных "ящиков" пикселя в каждом месте в этой сетке.

Возможно, часть информации на этом веб-сайте может быть объединена с тем, что у нас уже есть?

Обновление: я взял некоторые из того, что Андри написал с некоторыми из этого question, чтобы достичь этого, что довольно близко к тому, что я задумывал: heatmap

numbet <- 20
numtri <- 100
prob=1/6
#Fill a matrix 
xcum <- matrix(NA, nrow=numtri, ncol=numbet+1)
for (i in 1:numtri) {
  x <- sample(c(0,1), numbet, prob=c(prob, 1-prob), replace = TRUE)
  xcum[i, ] <- c(i, cumsum(x)/cumsum(1:numbet))
}
colnames(xcum) <- c("trial", paste("bet", 1:numbet, sep=""))

mxcum <- reshape(data.frame(xcum), varying=1+1:numbet, 
  idvar="trial", v.names="outcome", direction="long", timevar="bet")

 #from the other question
 require(MASS)
dens <- kde2d(mxcum$bet, mxcum$outcome)
filled.contour(dens)

Я не совсем понимаю, что происходит, но это похоже на то, что я хотел создать (очевидно, без разного размера).

Обновление: это похоже на другие графики здесь. Это не совсем правильно:

hexbin

plot(hexbin(x=mxcum$bet, y=mxcum$outcome))

Последняя попытка. Как указано выше: enter image description here

image(mxcum$bet, mxcum$outcome)

Это очень хорошо. Я просто хотел бы, чтобы это выглядело как мой рисованный эскиз.

Ответ 1

Edit

Я думаю, что следующее решение делает то, о чем вы просите.

(Обратите внимание, что это медленно, особенно шаг reshape)

numbet <- 32
numtri <- 1e5
prob=5/6
#Fill a matrix 
xcum <- matrix(NA, nrow=numtri, ncol=numbet+1)
for (i in 1:numtri) {
  x <- sample(c(0,1), numbet, prob=c(prob, 1-prob), replace = TRUE)
  xcum[i, ] <- c(i, cumsum(x)/cumsum(1:numbet))
}
colnames(xcum) <- c("trial", paste("bet", 1:numbet, sep=""))

mxcum <- reshape(data.frame(xcum), varying=1+1:numbet, 
  idvar="trial", v.names="outcome", direction="long", timevar="bet")


library(plyr)
mxcum2 <- ddply(mxcum, .(bet, outcome), nrow)
mxcum3 <- ddply(mxcum2, .(bet), summarize, 
                ymin=c(0, head(seq_along(V1)/length(V1), -1)), 
                ymax=seq_along(V1)/length(V1),
                fill=(V1/sum(V1)))
head(mxcum3)

library(ggplot2)

p <- ggplot(mxcum3, aes(xmin=bet-0.5, xmax=bet+0.5, ymin=ymin, ymax=ymax)) + 
    geom_rect(aes(fill=fill), colour="grey80") + 
    scale_fill_gradient("Outcome", formatter="percent", low="red", high="blue") +
    scale_y_continuous(formatter="percent") +
    xlab("Bet")

print(p)

enter image description here

Ответ 2

FYI: Это скорее расширенный комментарий, чем ответ.

Для меня этот новый сюжет выглядит как уложенный столбик, где каждая высота бара равна точке пересечения верхней и нижней линии при следующем испытании.

enter image description here

Способ, которым я хотел бы подходить к этому, - относиться к "Испытаниям" как к категориальной переменной. Затем мы можем искать каждую строку xcum для одинаковых элементов. Если они есть, то мы можем считать это точкой пересечения, минимумы которой также представляют собой кратное, определяющее высоту наших баров.

x <- t(xcum)
x <- x[duplicated(x),]
x[x==0] <- NA

Теперь мы имеем кратность фактических точек, нам нужно выяснить, как перейти к следующему шагу и найти способ биннинга информации. Это означает, что нам нужно принять решение о том, сколько очков будет представлять каждая группировка. Позвольте написать некоторые замечания для потомков.

Trial 1 (2) = 1, 0.5 # multiple = 0.5
Trial 2 (3) = 1, 0.66, 0.33 #  multiple = 0.33
Trial 3 (4) = 1, 0.75, 0.5, 0.25 # multiple = 0.25
Trial 4 (5) = 1, 0.8,  0.6, 0.4, 0.2 # multiple = 0.2
Trial 5 (6) = 1, 0.8333335, 0.6666668, 0.5000001, 0.3333334, 0.1666667
... 
Trial 36 (35) = 1, 0.9722223, ..., 0.02777778 # mutiple = 0.05555556 / 2

Другими словами, для каждого испытания есть n-1 точки для построения. На вашем рисунке у вас есть 7 ящиков. Таким образом, нам нужно вычислить кратность для каждого бункера.

Пусть обманывают и делят последние два столбца на два, из визуального контроля мы знаем, что минимумы ниже 0,05

x[,35:36] <- x[,35:36] / 2

Затем найдите минимум для каждого столбца:

x <- apply(x, 2, function(x) min(x, na.rm=T))[-1] # Drop the 1
x <- x[c(1,2,3,4,8,17,35)] # I'm just guessing here by the "look" of your drawing. 

Самый простой способ сделать это - создать каждый бит отдельно. Очевидно, что это можно сделать автоматически позже. Помня, что каждая точка

bin1 <- data.frame(bin = rep("bin1",2), Frequency = rep(x[1],2))
bin2 <- data.frame(bin = rep("bin2",3), Frequency = rep(x[2],3))
bin3 <- data.frame(bin = rep("bin3",4), Frequency = rep(x[3],4))
bin4 <- data.frame(bin = rep("bin4",5), Frequency = rep(x[4],5))
bin5 <- data.frame(bin = rep("bin5",9), Frequency = rep(x[5],9))
bin6 <- data.frame(bin = rep("bin6",18), Frequency = rep(x[6],18))
bin7 <- data.frame(bin = rep("bin7",36), Frequency = rep(x[7],36))

df <- rbind(bin1,bin2,bin3,bin4,bin5,bin6,bin7)
ggplot(df, aes(bin, Frequency, color=Frequency)) + geom_bar(stat="identity", position="stack")