11

I want to print a bubble chart in R. The problem I run into is that both, my x and my y axis are discrete. In theory this means a lot of data points (bubbles) end up on the same coordinate. I would rather have them scattered around the data point, but still within a quadrant that makes clear the bubble belongs to the respective x/y coordinate.

I think it is best demonstrated by a little example. The following code should highlight the problem:

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

How can I scatter the bubbles a little bit to show the different products in each categories and their quantity?

(Apologies, I can't add an image at the moment because of too few reputations)

enter image description here

Docconcoct
  • 1,931
  • 3
  • 23
  • 41
Roman
  • 249
  • 1
  • 2
  • 7
  • Re your last note: add a link to the image to the post, someone with enough rep will likely replace it with the actual image. – tonytonov Nov 05 '14 at 15:43
  • Maybe you can you can use geom_jitter(...) instead of geom_point and maybe also use the alpha parameter to add transparency due to overlapping. – Tom Martens Nov 05 '14 at 19:52

1 Answers1

21

As Tom Martens pointed out adjusting alpha can show any overlapping. The following alpha level:

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

results in:

enter image description here

Using geom_jitter instead of point, combined with 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()

produces this:

enter image description here

EDIT: In order to avoid the artefact in the legend the alpha should be placed outside the 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()

resulting in:

enter image description here

and:

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

resulting in:

enter image description here

EDIT 2: So, this took a while to figure out.

I followed the example I linked to in my comment. I adjusted the code to suit your needs. First of all I created the jitter values outside of the plot:

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

I then called those values into the geom_point and geom_text x and y coordinates inside aes. This worked by jittering the bubbles and matching labels to them. However it messed up the x and y axis labels so I relabled them as can be seen in scale_x_discrete and scale_y_discrete. Here is the plot code:

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

Which gives this output:

enter image description here

You can adjust the size of the bubbles via scale_size above. I exported this image with dimensions of 1000*800.

Regarding your request to add borders I think it is unnecessary. It is very clear in this plot where the bubbles belong & I think borders would make it look a bit ugly. However, if you still want borders I'll have a look and see what I can do.

Docconcoct
  • 1,931
  • 3
  • 23
  • 41
  • That's almost perfect. Do you also know how to get the labels next to the respective bubble? Also, the suggestion of using geom_jitter is absolutely great. Exactly what was needed. However, now that the bubbles finally do what they are supposed to, how can I distinguish the different quadrants? Is there a way of drawing a rectangle (or so) around LocationA/High, LocationB/High and so on and so forth? +1 and accepted if labels issue sorted! – Roman Nov 06 '14 at 09:28
  • Will give +1 as soon as I have 15 reputation. Apologies. – Roman Nov 06 '14 at 09:29
  • I don't have time right now to solve that but something like: geom_text(hjust = 1, size = 3,position=position_jitter()) will stop lables overlapping but I suspect they will not match the bubbles. Check here for an idea of how to address that issue: http://stackoverflow.com/questions/6551147/adding-text-to-ggplot-geom-jitter-points-that-match-a-condition I'll have a look again tomorrow. – Docconcoct Nov 06 '14 at 19:12
  • 1
    Very good answer. Demonstrates all the key issues - Thank you very much – Zhubarb Apr 09 '15 at 10:13