14

这与另一个问题有关:绘制加权频率矩阵

我有这个图形(由下面的 R 代码生成):多样本

#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)

我非常喜欢这个情节的构建方式,并且将更频繁的路径显示为比罕见的路径更暗(但对于打印演示来说还不够清晰)。我想做的是为数字生成某种 hexbin 或热图。仔细想想,似乎情节必须包含不同大小的垃圾箱(见我的信封草图背面):

垃圾箱

那么我的问题是:如果我使用上面的代码模拟一百万次运行,我如何将其呈现为热图或 hexbin,以及草图中显示的不同大小的 bin?

澄清一下:我不想依靠透明度来表明通过情节的一部分进行审判的罕见性。相反,我想用热来表示稀有性,并用热(红色)表示一个共同的途径,用冷(蓝色)表示一个罕见的途径。另外,我不认为垃圾箱应该是相同的大小,因为第一个试验只有两个可以放置路径的地方,但最后一个有更多。因此,基于这一事实,我选择了一个不断变化的 bin 比例。本质上,我正在计算路径通过单元格的次数(第 1 列中的 2 次,第 2 列中的 3 次等),然后根据通过的次数为单元格着色。

更新:我已经有一个类似于@Andrie 的情节,但我不确定它是否比上面的情节清晰得多。我不喜欢这张图的不连续性(以及为什么我想要某种热图)。我认为因为第一列只有两个可能的值,所以它们之间不应该有巨大的视觉差距等等。因此我设想了不同大小的垃圾箱。我仍然觉得分箱版本会更好地显示大量样本。

情节2

更新:本网站概述了绘制热图的过程:

为了创建密度(热图)绘图版本,我们必须有效地枚举这些点在图像中每个离散位置的出现。这是通过建立一个网格并计算点坐标“落入”该网格中每个位置的每个单独像素“箱”的次数来完成的。

也许该网站上的一些信息可以与我们已经拥有的信息相结合?

更新:我拿了安德烈写的一些关于这个问题的内容来得出这个结论,这与我的设想非常接近: 热图

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)

我不太明白发生了什么,但这似乎更像我想要生产的(显然没有不同大小的垃圾箱)。

更新:这与此处的其他图类似。这不太对:

六边形

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

最后一次尝试。如上: 在此处输入图像描述

image(mxcum$bet, mxcum$outcome)

这很不错。我只想让它看起来像我的手绘草图。

4

2 回答 2

11

编辑

我认为以下解决方案可以满足您的要求。

(注意这很慢,尤其是这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)

在此处输入图像描述

于 2011-09-14T13:28:13.043 回答
3

仅供参考:这更像是一个扩展评论而不是答案。

对我来说,这个新图看起来像一个堆叠的条形图,其中每个条形图的高度等于下一次试验中上下线的交点。

在此处输入图像描述

我处理这个问题的方法是将“试验”视为一个分类变量。然后我们可以在 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

换句话说,对于每个 Trial,有 n-1 个点要绘制。在您的绘图中,您有 7 个垃圾箱。所以我们需要计算出每个 bin 的倍数。

让我们作弊,将最后两列除以二,我们通过目测知道最小值低于 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. 

最清晰的方法是分别创建每个 bin。显然,这可以稍后自动完成。记住每个点都是

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")
于 2011-09-05T13:37:35.197 回答