3

I would like to make my scatterplot circles shaded according to the value in one column.

"value"; "avg.sal"; "avg.temp"
2,5698; 34,27254; 4,44
5,4361; 34,30686; 4,64
2,27; 34,3538; 8,05
5,6015; 34,50136; 5,01
2,27; 34,37596; 7,4

I have my plot ready with salinity on the y-axis and temperature on the x-axis.

plot(df$avg.sal, df$avg.temp)

How do I shade the circles (e.g. from light blue to dark blue) according to the column "value"? The values have a big range but smaller values (e.g. 2) should be light blue and larger values (e.g. 10) should be dark blue. I would prefer not to use GGplot.

Bala
  • 67
  • 1
  • 7
  • You can use the `colorRampPalette`, see this post: http://stackoverflow.com/questions/13353213/gradient-of-n-colors-ranging-from-color-1-and-color-2 – user1981275 Sep 16 '13 at 12:01

1 Answers1

8
dat <- read.delim(text='"value"; "avg.sal"; "avg.temp"
 2,5698; 34,27254; 4,44
 5,4361; 34,30686; 4,64
 2,27; 34,3538; 8,05
 5,6015; 34,50136; 5,01
 2,27; 34,37596; 7,4"', sep=";", dec=",")

bluefunc <- colorRampPalette(c("lightblue", "darkblue"))
plot( dat$avg.sal, dat$avg.temp, 
              col=bluefunc(5)[findInterval(dat$value, seq(2:6))] )

To respond to the followup question. When cex is specified inside a vector it does control size of the "points":

dat$size <- 1:5
bluefunc <- colorRampPalette(c("lightblue", "darkblue"))
plot( dat$avg.sal,  dat$avg.temp,
            cex=dat$size,
            col=bluefunc(5)[findInterval(dat$value, seq(2:6))] )
IRTFM
  • 258,963
  • 21
  • 364
  • 487
  • thanks for the reply @DWin! I was also thinking if it is possible to at the same time make the circles bigger... for the colour it is possible to say 5 shades and specify the interval as above... could you also do the same for size of circles (e.g. light blue small circles and dark blue big cicles)? i saw this post [link](http://stackoverflow.com/questions/2579995/control-the-size-of-points-in-an-r-scatterplot) and [link](http://stackoverflow.com/questions/7133523/r-plot-make-a-big-circle-at-a-point?lq=1) but using symbols instead of the plot function does not help me. – Bala Sep 17 '13 at 07:25
  • Perhaps you were not offering a size-argument-vector to the that varied according to your desires? The `symbols` function does accept size vectors for 'circles', 'squares', 'rectangles', 'stars', and 'thermometers'. – IRTFM Sep 17 '13 at 15:42
  • sorry, i should rephrase my question a little bit.... from the dat file, rows 3 and 5 should be the lightest blue and smallest circles (but the same blue and same size because their value =2.27), next is row 1 (value=2.5698) a bit darker blue and a bit bigger circle, next row 2 (value=5.4) and lastly is row 4 (value=5.6) with the darkest blue and biggest circle... – Bala Sep 18 '13 at 08:12
  • If you wanted the size to follow the increase in "darkness" then just offer the same numeric argument to size that you are offering to the colorRamp function: `cex=findInterval(dat$value, seq(2:6))` – IRTFM Sep 18 '13 at 14:59
  • what if my value was much larger... say until 240... then is it possible to have values 0-20 as the lightest shade of blue, then 21-40.. 41-60... until 221-240 with the darkest shade of blue... This would mean bluefunc(12)... Thank you! – Bala Sep 23 '13 at 14:28
  • You just need to change the second argument to the findInterval function to vary the cutpoints for color. – IRTFM Sep 23 '13 at 15:52
  • `col=bluefunc(12)[findInterval(dat$value, seq((0:240)/20))]` this works for me but i am not sure if this is what you had told me to do.. Also when R is plotting, I tried to use `identify(x=dat$avg.sal,y=dat$avg.temp)` to see if my darker points were plotted above.. Is there a possible way to know for sure that R plots darker points above lighter points? I arranged my csv file so that it reads from smallest to largest on the value column but I'm not sure if that really did the trick.. – Bala Sep 24 '13 at 10:31
  • I don't know what the phrase "plots darker points above lighter points" means in the context of data I have never seen. If you cannot see whether you are getting the correct result why not create a test dataset where the result is more obvious? – IRTFM Sep 24 '13 at 12:49
  • i am working with datasets from different years... for e.g. 1986 only has values from 0 to 20 but for 2008 the values are from 0 to 240... this causes a problem since some points do not show up, depending on bluefunc(5) or bluefunc(12) for example... let's say I know my maximum value is 240... but in the case of 1986, i want my max to be 240, although 1986's max value is 20... this means 1986 would not have dark shades of blue... only in 2008 will i see dark shades of blue... since 0-20 is the lightest shade and 220-240 is the darkest shade... – Bala Sep 24 '13 at 13:45
  • when R plots, avg.sal of 34,50 and 34,51 are side by side... i could change the scale of the axis so they seem further apart, but i do not wish to do that... so these 2 points can seem really close together.. if 34,50 has value 20 and 34,51 has value 240 (no CEX is done, so both points are the same, only differentiated by colour).. how do i know R is plotting point 34,51 above 34,50 so the darker point is above the lighter point? I did a test datasheet and it seems like R plots according to row... meaning row 1 is plotted first and row 99 is plotted last for example.. can I be sure of this? – Bala Sep 24 '13 at 13:48
  • Yes. The plotting model is "ink". It's not always totally opaque, but with these colors it's not intended to be transparent ink and the default transparency is very low. If you want the dark blue to plot over light blue, then reorder to the data using `order`. – IRTFM Sep 24 '13 at 17:37
  • yes I will use `order`, but I am still struggling with the first comment about 0-20 lightest blue and 220-240 darkest blue, although different years have different maximum values... R is still giving me darkest blue (reserved for 220-240) in 1986, when the max value in 1986 is only 20... – Bala Sep 25 '13 at 08:24
  • i added `v=c(0,19,39,59,...,199,219,239)` so v divides by 20 each from 0 till 239... then i called `col=bluefunc(12)[findInterval(dat$value, v)]`. This seems correct, could you verify that I am doing it correctly? – Bala Sep 25 '13 at 10:17
  • It sounds like it might be correct, but I cannot "verify", because you have never edited your question to construct a complete working example. – IRTFM Sep 25 '13 at 12:49