使用ggplot2绘制气泡图

11

我想在R中打印一个气泡图。 我遇到的问题是我的x轴和y轴都是离散的。 理论上,这意味着许多数据点(气泡)最终会出现在同一坐标上。 我宁愿将它们散布在数据点周围,但仍位于显示该气泡属于相应x / y坐标的象限内。

我认为最好通过一个小例子来演示。以下代码应突出显示问题:

# Example
require(ggplot2)
zz <- textConnection("Row PowerSource ProductSegment Price Model ManufacturingLocation Quantity
1 High SegmentA Low ModA LocationA 5000
2 Low SegmentB Low ModB LocationB 25000
3 High SegmentC Low ModC LocationC 15000
4 Low SegmentD High ModD LocationD 30000
5 High SegmentE High ModE LocationA 2500
6 Low SegmentA Low ModF LocationB 110000
7 High SegmentB Low ModG LocationC 20000
8 Low SegmentC Low ModH LocationD 3500
9 High SegmentD Low ModI LocationA 65500
10 Low SegmentE Low ModJ LocationB 145000
11 High SegmentA Low ModK LocationC 15000
12 Low SegmentB Low ModL LocationD 5000
13 High SegmentC Low ModM LocationA 26000
14 Low SegmentD Low ModN LocationB 14000
15 High SegmentE Mid ModO LocationC 75000
16 Low SegmentA High ModP LocationD 33000
17 High SegmentB Low ModQ LocationA 14000
18 Low SegmentC Mid ModR LocationB 33000
19 High SegmentD High ModS LocationC 95000
20 Low SegmentE Low ModT LocationD 4000
 ")
df2 <- read.table(zz, header= TRUE)
close(zz)
df2


ggplot(df2, aes(x = ManufacturingLocation, y = PowerSource, label = Model)) +
    geom_point(aes(size = Quantity, colour = Price)) + 
    geom_text(hjust = 1, size = 2) +
    scale_size(range = c(1,15)) +
    theme_bw()

如何将气泡稍微分散一些,以展示每个类别中不同产品及其数量?

(抱歉,由于声望不足,我暂时无法添加图像)

输入图像说明


根据您最后的留言:请在帖子中添加图像链接,有足够声望的人可能会将其替换为实际图像。 - tonytonov
也许你可以使用 geom_jitter(...) 代替 geom_point,并可能还要使用 alpha 参数添加透明度以解决重叠问题。 - Tom Martens
1个回答

21

正如Tom Martens所指出的,调整alpha值可以显示任何重叠情况。以下是alpha水平:

ggplot(df2, aes(x = ManufacturingLocation, y = PowerSource, label = Model)) +
    geom_point(aes(size = Quantity, colour = Price, alpha=.02)) + 
    geom_text(hjust = 1, size = 2) +
    scale_size(range = c(1,15)) +
    theme_bw()

结果为:

图片描述

使用geom_jitter代替point,并结合alpha参数:

ggplot(df2, aes(x = ManufacturingLocation, y = PowerSource, label = Model)) +
    geom_jitter(aes(size = Quantity, colour = Price, alpha=.02)) + 
    geom_text(hjust = 1, size = 2) +
    scale_size(range = c(1,15)) +
    theme_bw()

生成这个:

在此输入图片描述

编辑:为了避免图例中的伪像,alpha应该放在aes外面:

ggplot(df2, aes(x = ManufacturingLocation, y = PowerSource, label = Model)) +
    geom_point(aes(size = Quantity, colour = Price),alpha=.2) +
    geom_text(hjust = 1, size = 2) +
    scale_size(range = c(1,15)) +
    theme_bw()
导致:

这里输入图片描述

以及:
 ggplot(df2, aes(x = ManufacturingLocation, y = PowerSource, label = Model)) +
    geom_jitter(aes(size = Quantity, colour = Price),alpha=.2) +
    geom_text(hjust = 1, size = 2) +
    scale_size(range = c(1,15)) +
    theme_bw()

导致:

在此输入图像描述

编辑2:所以,这花了一段时间才弄明白。

我按照我在评论中提供的示例进行了操作。我调整了代码以适应您的需求。首先,我在绘图之外创建了抖动值:

df2$JitCoOr <- jitter(as.numeric(factor(df2$ManufacturingLocation)))
df2$JitCoOrPow <- jitter(as.numeric(factor(df2$PowerSource)))

然后我在 aes 内部调用那些值,作为 geom_point 和 geom_text 的 x 和 y 坐标。这样可以让气泡微移并匹配标签。但是它弄乱了 x 和 y 轴标签,所以我使用 scale_x_discrete 和 scale_y_discrete 进行重新标记。以下是绘图代码:

ggplot(df2, aes(x = ManufacturingLocation, y = PowerSource)) +
geom_point(data=df2,aes(x=JitCoOr, y=JitCoOrPow,size = Quantity, colour = Price), alpha=.5)+
geom_text(data=df2,aes(x=JitCoOr, y=JitCoOrPow,label=Model)) + 
scale_size(range = c(1,50)) +
scale_y_discrete(breaks =1:3 , labels=c("Low","High"," "), limits = c(1, 2))+
scale_x_discrete(breaks =1:4 , labels=c("Location A","Location B","Location C","Location D"), limits = c(1,2,3,4))+ 
theme_bw()

输出结果如下所示:

在此输入图片描述

你可以通过设置 scale_size 来调整气泡的大小。我导出了这张图片,大小为1000*800。

关于您要求添加边框的问题,我认为这是不必要的。在这个图中,气泡所属的位置非常清晰,而且我认为边框会让它看起来有点丑。但是,如果你仍然想要边框,我会看看能做些什么。


这几乎是完美的。你是否也知道如何在相应的气泡旁边获取标签?此外,使用geom_jitter的建议绝对棒极了。正是所需的。然而,现在气泡终于做到了它们应该做的事情,我如何区分不同的象限?是否有一种方法在LocationA/High、LocationB/High等周围画一个矩形(或类似的东西)?如果标签问题解决了,+1并接受! - Roman
抱歉,我需要达到15个声望才能给您点赞。 - Roman
我现在没有时间解决这个问题,但是像geom_text(hjust = 1, size = 3,position=position_jitter())这样的代码可以防止标签重叠,但我怀疑它们可能与气泡不匹配。请参考这里的解决方案:https://dev59.com/Q1jUa4cB1Zd3GeqPU9SQ 我明天再看一下。 - Docconcoct
1
非常好的回答。展示了所有关键问题 - 非常感谢。 - Zhubarb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接