【问题标题】:Creating a log axis in a 100% stacked column chart in R with ggplot使用 ggplot 在 R 中的 100% 堆叠柱形图中创建对数轴
【发布时间】:2013-09-06 06:23:39
【问题描述】:

我有百分比数据。我想使用 ggplot 创建一个图表,但我无法让它像我想要的那样工作。由于数据非常倾斜,因此简单的堆叠列效果不佳,因为不会显示非常小的值。这是一个样本集:

    Actual  Predicted
a   0.5     5
b   9.5     5
c   90      90

左边是excel图,右边是R-ggplot

问题在于,在 R 中,列堆叠起来并不均匀。

这是我的 R 代码:

a = c("a","b","c","a","b","c")
b = c("Actual","Actual","Actual","Predicted","Predicted","Predicted")
c = c(0.5,2.5,97,0.2,2.2,97.6)
c = c+1

dat = data.frame(Type=a, Case=b, Percentage=c)
ggplot(dat, aes(x=Case, y=Percentage, fill=Type)) + geom_bar(stat="identity") + scale_y_log10()

*在 Excel 和 R 中,我都会 +1 来处理数字 0-1,所以 y 轴会稍微偏离

如果我使用:

ggplot(dat, aes(x=Case, y=Percentage, fill=Type)) + geom_bar(stat="identity",position = "fill") + scale_y_log10()

总高度匹配,但是两个蓝色部分的大小不匹配(它们都是 90%)

【问题讨论】:

  • 这个问题也可以迁移到 Crossvalidated。

标签: r excel graph plot ggplot2


【解决方案1】:

仅仅因为两组数字加起来是相同的值(在本例中为 103)并不意味着对数的总和会加起来相同的值!当您堆叠没有“填充”的条时,您会得到不同的高度,因为值的对数总和不同。然后,当您将其全部缩放到相同的高度时,您必须以不同的速率将蓝色框压扁,因此它们看起来会有所不同。

Excel 条形图故意误导。左边的红色条与其上方的蓝色条大小相同,但代表的值约为蓝色条的十分之一。你不能在比例的对数比例上制作条形图——这是错误的。

有一种绝妙的方法可以显示小数字而不会丢失或歪曲它们。它是一种令人惊叹的可视化技术,称为“将数字写入表格”。

【讨论】:

  • 是的,我意识到这是一个 log(a+b) != log(a)+log(b) 的事情。 excel 版本在视觉上具有误导性,但在数字上是正确的。你看不到(我把它缩小太多了)是中心刻度是 10%,所以基本上左边的红色条从 0 到 10% 是正确的。
  • 另外,“将数字写入表格”也不是可视化。当我有一张 10x30 的桌子时,没有人会看它。您将看不到模式和不一致之处。
  • 将数据绘制为点,而不是条形。想想你试图讲述的故事。您是在谈论实际和预测的差异吗?绘制差异。等
【解决方案2】:

我设法让它像 excel 一样工作。就像 Spacedman 所说的那样,该情节在视觉上具有误导性,但在数字上是正确的。原因是我们想要比较条形段的实际高度,而在数值上您需要查看 y 轴的开始值和结束值。它类似于没有 y 轴最小值为零的条形图。这是example

我不确定我是否会使用该方法来可视化我的数据,但我必须弄清楚。

结果如下:

这是代码(我可能会将其清理为一个函数,当您在 ggplot 中分配 y 值时可以调用该函数)。

a = c("a","b","c","a","b","c")
b = c("Actual","Actual","Actual","Predicted","Predicted","Predicted")
c = c(0.5,9.5,90,5,5,90)
c = c+1
dat = data.frame(Type=a, Case=b, Percentage=c, Cumsum_L=c, Cumsum=c, Norm=c)
for(i in 1:length(dat$Percentage)){
    cumsum=0
    for(j in 1:i){
        if(dat$Case[j]==dat$Case[i]){
            cumsum=cumsum+(dat$Percentage[j])
        }
    }
    dat$Cumsum_L[i]=cumsum-dat$Percentage[i]
    dat$Cumsum[i]=cumsum
    if(dat$Cumsum_L[i]==0){
        dat$Cumsum_L[i]=1
    }
    dat$Norm[i] = log(dat$Cumsum[i])-log(dat$Cumsum_L[i])
}
intervals = seq(from = 0, to = 100, by = 10)
intervals_log = log(intervals)
intervals_log[1]=0

ggplot(dat, aes(x=Case, y=Norm, fill=Type)) + geom_bar(stat="identity") +
    scale_y_continuous(name="Percent",breaks = intervals_log, labels=intervals )

*我还需要修复端点+1。

**我也可能在扼杀数学。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-15
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多