0

I have a 500x500 cell matrix that is updated on every iteration. I'm modelling stochastic processes and new values appear or disappear as a consequence. What i want to do is to give the values -1 and 0 a fixed colorcode (lets say green and blue). All other values (from 1 up to the maximum value found in the matrix) could be anything but the same colors as cells containing -1 or 0. The colors could be interpolated for all values greater than 0. I'm aware of the caxis function but this lets me only exclude the values -1 and 0 or interpolate starting at -1. Is there any solution to this problem? It needs to be a fast solution as well since the matrix is printed on every iteration...

[solution]

tic
a = randi([-1,10],100,100);
cint = [-1,0,linspace(1,10,10)];
cmap = [0,0,1;0,1,0;autumn(10)];
[~,c] = histc(a,cint);
d = cmap(reshape(c,10000,1),:);
for k=1:3
    im(:,:,k) = reshape(d(:,k),100,100);
end
image(im)    
toc
tadzi
  • 89
  • 1
  • 9
  • 3
    I think your question is slightly unclear because you have not provided any example of the cell matrix that you are working on/want to work on. I might be wrong, but I cannot starnt I suggest you re-write the question with the cell matrix so that we can get a better picture. – ha9u63a7 Aug 15 '14 at 10:45
  • 1
    If I understand you correctly, you can create a custom colormap for this just keeping that initial range a constant colour: http://stackoverflow.com/questions/17230837/how-to-create-a-custom-colormap-programatically/17232355#17232355 if you go this route I suggest you choose a maximum (colour) value upfront and keep it constant – Dan Aug 15 '14 at 10:59
  • It is a little bit unclear here. It seems that you asks for two things here and mix them both up with each other. You mention both that you want to assign a color to a value and also that you want to interpolate colors. Which one do you have a problem with? Also, are the "cell matrix" supposed to represent an image? In that case I would recommend you to use a 3d matrix as matlab does. – patrik Aug 15 '14 at 11:20
  • The matrix contains -1's, 0's and a variable number of positive numbers. I want to print the matrix as an image whereby -1 values are displayed as green cells, 0 values as blue and all other values can be interpolated colors but should differ from the color of -1 and 0 cells (they can not be of the same color!). So say that my maximum value is 500. If i use the default settings, matlab will interpolate the colors from -1 to 500. I want to fix the colors of -1 and 0 values and start interpolating with different colors from 1 onwards. @Dan, seems that's what im looking for. Will try it in a bit! – tadzi Aug 15 '14 at 11:48

2 Answers2

1

Well since you specifically asked for a cell.

a = randi([-1,10],10,10); % Generate a 10x10 matrix of random integers
a = num2cell(a);
b = [-1,0,linspace(1,10,5)]; % color interval
cmap = [0,1,0;0,0,1;hot(5)]; % colormap with 7 colors
[~,c] = cellfun(@(x) histc(x,b), a, 'un', false); % Find color index
imdataCells = cellfun(@(x) cmap(x,:), c,'un', false); % Get colors

I have not tested to create an image of the data, but as far as I see (by looking at the data and comparing a with the interval) it should work.

EDIT

To get the image data in the right format it is then possible to transform the image data with cellfun

foo = zeros(size(a,1),size(a,2),3);
for k = 1:3
foo(:,:,k) = cellfun(@(x) x(k),imdataCells);
end
patrik
  • 4,506
  • 6
  • 24
  • 48
  • This seems to work up till the point when I have to output the cell array as a colormap. How can i accomplish this? I tried `cellfun(@colormap, imdataCells)` `cellfun(@image, imdataCells)` Doesn't work. I don't want to use loops since it has to be fast and my original matrix contains from 200^2, to 500^2 entries... – tadzi Aug 21 '14 at 12:56
  • Btw, it does not have to be a cell. I guess it's easier to have a a 3d matrix containing RGB values and then to use `colormap` no? – tadzi Aug 21 '14 at 13:05
  • What do you mean with a colormap? `cmap` is the colormap. That one is completely independent of your data. The colormap does only specify which colors you use. Do you mean that you want the image data in the right format (a 3d matrix)? – patrik Aug 21 '14 at 13:36
  • @user3398082 I think so too, but OP asked for a cell. I guess that otherwise you do the same, but without cellfun – patrik Aug 21 '14 at 13:38
  • i was confused about the colormap. thought it was a command to output a matrix with RGB values as an image. But it works now! I tweaked your code, not using cell arays and it also seems to be faster this way (see my OP). Thanks for you help! – tadzi Aug 21 '14 at 14:26
  • @user3398082 Well that is fair enough, matrices are in general faster than cells and should always be the first option. And regarding the colormap: it only does the color mapping when applied to an axes. So to say maps one chart to another. – patrik Aug 22 '14 at 06:32
-1

The 4th argument of for instance surf() is a matrix for the color of the values, you can either change this or change the used colormap. This approach simpy defines a colormap to your needs:

% Your Data of -1's, 0's and positive values
cdata = num2cell(peaks(500));
cdata = cell2mat(cdata);
cdata(cdata<0) = -1;
cdata(cdata>0 & cdata <1) = 0;

% the plot
figure()
h = imagesc(cdata);

% the colors
N = 20; % number of colors for interpolation
blue2red = zeros(N,3);
for k = 1:N
    blue2red(k,:) =[k/N, 0, 1-k/N];
end

% adjust the colormap
cmap = zeros(N+2,3);
cmap(1,:) = [0,1,0]; % first is green (for -1)
cmap(2,:) = [0,0,1]; % second is blue (for 0)
cmap(3:end,:) = blue2red; % all the rest is an interpolation from blue to red
colormap(cmap)
colorbar

% Test the picture whilst values are updating
for k = 1:1000;
% Test the picture whilst values are updating
for k = 1:1000;
    old_cdata = get(h, 'CData');        
    cdata = old_cdata + (rand(size(cdata))-0.5)*0.1; % assume values get updated
    cdata(cdata<0) = 0; % assume positive values are at least 0
    cdata(old_cdata == -1) = -1; % assume -1 stays -1
    cdata(old_cdata == 0) = 0; % assume 0 stays 0
    set(h, 'CData', cdata);
    drawnow
end
end
Nras
  • 4,251
  • 3
  • 25
  • 37
  • Well this is kind of cheating, is it not? Not to think of that you will get up the ugliest surf plot ever seen. Also, the initial assumption is that the variable you call `Z` must be a cell and not a matrix. This can of course be modified with `cell2mat`. However, your example does not works as intended. Try to replace `cmap(3:end,:) = blue2red;` with `cmap(3:end,:) = hot(size(cmap(3:end,:),1));` and you will see. – patrik Aug 15 '14 at 13:06
  • @patrik i cannot follow your critique. I updated my post and exchanged surf by imagesc and added a test for an updating picture. I don't think it looks like the ugliest surf plot ever seen. It looks exactly like i expected and like i understood the problem. Please enlighten me. – Nras Aug 15 '14 at 13:40
  • Well surf is 3d and random and 3d does not go well together. However did you try my test? This shows that the code put up by you does not even work as intended. Also OP especially ask for color codes. I cannot see the thus this is not an answer – patrik Aug 18 '14 at 06:14