Reputation: 1745
I am running a simulation that competes two types of agents against each other. Let's call these agents "red" and "blue." There are three possible outcomes: red wins, blue wins, or everyone loses. Let's say, also, that the system depends on two parameters: X and Y.
What I would like to do is create a pseudocolor plot that encodes outcome as a function of X and Y.
The hue of every point is the likelihood that either red or blue wins, given that somebody wins. If blue always wins, it's blue; if red always wins, it's red; etc.
The saturation is the probability that anyone wins. So if nobody ever wins at some value of X and Y, that point will be grey (in an HSV model, anyway).
EDIT: So let's say that we're using an HSV model as encoded here. (It doesn't have to be that, but let's say that it is.) Pure blue is (240, 100, 100) in HSV space and pure red is (360, 100, 100). Suppose, too, that red wins 50% of the time, blue wins 25% of the time, and nobody wins 25% of the time. Then this point will be (330, 75, 100).
Note that I'm not worried about converting from HSV to RGB -- for that, I can just use col2rgb(hsv(...))
. The issue is the plotting itself. The image() function, as far as I can tell, can only encode one channel of information; this is two channels of information.
Additionally, the outcome is a continuous function of X and Y, so I want to interpolate between the values. (I am using the 'akima' package for that, if it matters.) Hence the solution that I found here doesn't help me (I think).
I'm happy to use any package. I'm also happy to not use R, as long as the result is pretty and isn't too involved.
Thank you for any help you can offer.
Upvotes: 2
Views: 1379
Reputation: 49640
If you can create an array with the rgb values (dimensions 1 and 2 refer to your matrix, dimension 3 is the red, green, and blue components) then you can plot this with the rasterImage
function.
A simple example (I will leave converting the hsv -> rgb to you):
red <- matrix( runif(100), 10, 10 )
blue <- matrix( runif(100), 10, 10 )
rgb.mat <- array( dim=c(10,10,3) )
rgb.mat[ , ,1 ] <- red
rgb.mat[ , ,2 ] <- 0
rgb.mat[ , ,3 ] <- blue
plot.new()
plot.window(xlim=c(0,1),ylim=c(0,1))
rasterImage( rgb.mat, 0,0,1,1 ) # interpolate
rasterImage( rgb.mat, 0,0,1,1, interpolate=FALSE ) # don't
Upvotes: 3
Reputation: 206167
Here's an attempt. I highly doubt it's the best way, but in theory it's possible. I just manually create different color levels and assign each observed value to the correct color level.
#put two "channels" of informaion in matrices
mpRed<-matrix(runif(5*5), nrow=5)
mpAny<-matrix(runif(5*5), nrow=5)
#define break points for colors/saturation
colBr<-seq(0,1, length.out=3)
satBr<-seq(0,1,length.out=5)
#now categorize observed values
vcRed<-cut(mpRed, colBr, labels=F)
vcAny<-cut(mpAny, satBr, labels=F)
vcComb<-as.numeric(interaction(vcRed, vcAny))
mcComb<-matrix(vcComb, ncol=ncol(mpAny))
#create colors for each of the levels
cols<-as.vector(outer(colBr[-1], satBr[-1],
FUN=function(a,b) hsv(ifelse(a>.5,1,.667),b,1)))
#make plot
with(dd, image(mcComb, col=cols, breaks=(0:length(cols))+.5))
Upvotes: 2