17

I want to plot my data as a dotplot using geom_point. My datapoints are overlapping, so I want to use jitter and transparency to increase visibility. Now I would also like to add a border to every datapoint to make it even more easier for the reader to see each datapoint. However, due to the alpha, it looks like my datapoints have halos around them. That's why I would like to use alpha only for the filling and alpha=0 for the border. But so far I haven't found a solution. I could plot two geom_points one being slightly larger than the other to create a border around each point with alpha=0. But becuase I need jitter, the same datapoints won't lie on top of each other. Does anyone has an idea how to solve this problem?

Here is my code:

ggplot(data=comp24, aes(x=spatial, y=lnfit, colour=spatial, fill=spatial, shape=spatial, backgroundColor="white", na.rm=T))+
geom_point(position=position_jitter(w=0.5), size=1.75, alpha=0.2, stroke=0.3)+
scale_colour_manual(name="spatial structure", values = c("black", "black", "black"))+
scale_fill_manual(name="spatial structure", values = c("black","black", "black"))

And some data:

spatial focal competitor       lnfit
low   pco        pch -1.79175947
low   pco        pch -1.49165488
low   pco        pch -0.98082925
low   pco        pch -1.97716269
intermediate   pco        pch -0.84729786
intermediate   pco        pch -0.48379695
intermediate   pco        pch -0.64574494
intermediate   pco        pch -0.51082562
intermediate   pco        pch  1.43693809
high   pco        pch  0.89608802
high   pco        pch  0.04879016
high   pco        pch -2.20625398
high   pco        pch  0.31003898
high   pco        pch -0.01694956

Here is a detail of the graph, that shows the halo I am talking about. I guess it comes from filling and border overlapping a bit. That's why I see this draker line within the grey area. Changing the stroke value unfortunately only increases the halo effect.

I save my graphs as .tif with:

tiff('C:/_..._..._.tif', bg = "white", res = 1600, width = 115, height = 160, units = "mm", compression="lzw")

Looking forward to your suggestions.

Cheers Anne

Anne
  • 241
  • 1
  • 3
  • 9
  • See http://stackoverflow.com/questions/19506630/control-point-border-thickness-in-ggplot and http://stackoverflow.com/questions/37381684/ggplot-alpha-levels-appear-different-on-fill-and-border-of-points – Robert Sep 23 '16 at 13:56

3 Answers3

7

This should works for you :

ggplot(data=comp24, aes(x=spatial, y=lnfit, colour=spatial, fill=spatial, shape=spatial, backgroundColor="white", na.rm=T))+
geom_point(position=position_jitter(w=0.5), size=1.75, stroke=0.3)+
scale_colour_manual(name="spatial structure", values = c("black", "black", "black"))+
scale_fill_manual(name="spatial structure", values =alpha(c("black","black", "black"),0.2))

Let me know

R_SOF
  • 268
  • 1
  • 7
  • 2
    Your code doesn't work. `scale_shape_manual(name="spatial structure", values = c(21:23))` is needed. – cuttlefish44 Sep 23 '16 at 13:59
  • with adding scale_shape_manual and playing around with the alpha and stroke values, I got a very nice result. Thank you! – Anne Sep 27 '16 at 12:57
  • @cuttlefish44. after spending the evening trying to add stroke to multiple shapes with multiple colors, your answer saved the day. Thanks again. I wish R_SOF can update the answer for future readers (since I did came across this answer before but missed the comment entirely. – Urvah Shabbir Dec 07 '18 at 17:59
  • 2
    Why does this have `backgroundColor="white"` and `na.rm=T` in the `aes`? – Axeman Jan 23 '20 at 00:47
6

A simpler way, available here because you want the same alpha and color for all, is to specify the fill in the geom_point command using alpha. Alternatively one could also "old-fashioned" method of specifying transparency with two additional hex codes, like this, #00000044.

ggplot(data=comp24, aes(x=spatial, y=lnfit, shape=spatial)) +
   geom_point(position=position_jitter(width=0.5), size=1.75, 
              fill=alpha("black", 0.2), stroke=0.3)
Aaron left Stack Overflow
  • 36,704
  • 7
  • 77
  • 142
1

To achieve the desired plot I will use position_nudge function.

First I create a nudge vector with a uniform probability distribution of the same length as the data points. This can be done as below

set.seed(10)
nudgeWidth = 0.5
nudgeVec <- (runif(nrow(comp24))-0.5)*nudgeWidth

Now I use the above nudge vector "nudgeVec" to get the desired plot

plot1 <- ggplot(data=comp24, aes(x=spatial, y=lnfit, backgroundColor="white", na.rm=T))
plot1 <- plot1 + geom_point(position=position_nudge(x = nudgeVec),size=10.75,aes(alpha=0.2, stroke=0.5,shape=(as.integer(comp24$spatial)+14)))
plot1 <- plot1 + scale_colour_identity()
plot1 <- plot1 + scale_shape_identity()
plot1 <- plot1 + geom_point(position = position_nudge(x = nudgeVec),size=10.75,aes(alpha=1, stroke=0.5, colour="black",shape=(as.integer(spatial)-1)))
plot1

The output looks like this Desired Plot

9Heads
  • 688
  • 3
  • 7
  • Thank you for your answer! I tried your code. It works for a simple plot. But downstream of the code I provided in the question, I'm going to add a separate set of points, include facetting... and then the shapes are somehow mixed up and don't fit to the edges anymore. Probably I don't understand what the code does and implement it wrong. – Anne Sep 27 '16 at 13:17
  • I have created a uniform variation in range of (-0.5 to 0.5) about the line corresponding to the high,intermediate and low. You can control the range of variation by changing the multiplication factor nudgeWidth. Also shapes will get mixed up if you have more than 3 factors level in the spatial field or your spatial field is of type character rather than factor, since the shapes are hard coded in the code above. – 9Heads Sep 28 '16 at 08:27