Colormatrix from colorvector - matlab

I have a scatter3 plot in which I use a vector C to define the colors of the different points. Here the color of the colormap is linearly mapped onto the numbers which are in C. I want to somehow find the RGB-values of each value inside my C vector. So I want a x by 3 matrix out of my C vector. Anybody knows if this is possible?
Best wishes,
Achim
Edit:
Thanks to #Aabaz I was able to solve the problem. Here is my solution:
colors_current = colormap;
color = [color zeros(length(color),2)];
stepw = floor(length(color)/length(colors_current));
colorsort = sortrows(color);
color_old = 0;
counter = 1;
for i = stepw:stepw:length(JAbs)
color_indices = find(color_old < color(:,1) & color(:,1) < color_sort(i));
if counter >= length(colors_current)
break;
end
for j=1:length(color_indices)
JAbs(color_indices(j),:) = colors_current(counter,:);
end
color_old = colorsort(i);
counter = counter + 1;
end
Not the most elegant way but it seems to work.

The function colormap used with no argument, returns the current axes colormap as an m by 3 matrix storing the RGB codes for each color. From there you can get to the RGB code for every element in your vector C.
UPDATE: I am sorry, I must have misread your question because I did not understand you were looking for an explicit way to get the rgb codes, just the connexion between the colormap and the rgb code. Anyway I see you found the solution yourself, well done. Did a quick try myself which I give you here :
n=10;
C=rand(n,1);
map=colormap(jet);
Cregspaced=(min(C):(max(C)-min(C))/(size(map,1)-1):max(C))';
Cmapindex=interp1(Cregspaced,(1:size(map,1))',C,'nearest');
Crgb=map(Cmapindex,:);
This should work, depending on how Matlab interpolates the index for the colormap. You can test it against your own solution to see if the results match.

Related

align regression equation at correct position in matlab

let us suppose we have following code
function plot_test(x,y)
x_constucted=[ones(size(x)) x];
b = regress(y,x_constucted);
y_predicted=b(1)+b(2)*x;
scatter(x,y);
hold on
plot(x,y_predicted);
theString = sprintf('y = %.3f*x+%.3f ', b(2), b(1));
text(x(1), y_predicted(1), theString, 'FontSize', 8);
end
output of this equation is the following figure
my question is : how to align equation out of line? for instance on top left size? thanks in advance
If I understand you correctly, you want to move the printed equation out of the dots. Check out the text() function description. The first two values define the x and y position in your plot for the text.
x=1;
y=25;
To move it up, use the new variables in text(x,y,...). Hope that helps.
Some time ago I was looking for a solution for the same exact problem. As you may know, the legend command allows to specify a Location parameter and one of its many options is called best, described in the official Matlab documentation (here) as follows:
Inside axes where least conflict occurs with plot data
My workaround abuses this feature in order to find the best location to place a single text annotation inside the plot. The code below uses a build-in dataset since you didn't specify how your data looks like:
load carsmall;
x = [ones(size(Horsepower)) Horsepower];
y = MPG;
b = regress(y,x);
y_hat = b(1) + b(2) .* Horsepower;
scatter(Horsepower,y);
hold on;
plot(Horsepower,y_hat);
text_at_best(sprintf('y = %.3f*x+%.3f ',b(2),b(1)),'FontSize',12);
function h = text_at_best(txt,varargin)
l = legend(txt,[varargin{:}]);
t = annotation('textbox',varargin{:});
t.String = txt;
t.Position = l.Position;
t.LineStyle = 'None';
delete(l);
if nargout
h = t;
end
end
Here is the final result:
I don't know if this can fit your needs... but developing an algorithm for finding a non overlapping part of the plot in which to place a text looked like an overkill to me. Despite the text being quite far from the prediction line, it's still elegant, clear and comprehensible. The same goes with an even quicker workaround which consists in setting the regression equation as the plot title (blink blink).

Trying to apply a color map to a bar graph in MATLAB

I have a collection of data that I am trying to graph as a histogram. Additionally, I would like to color the individual bars as a function of the x axis location. CData, described here seems to do what I want but I can't get it to work.
Here is my code:
h = bar(new_edge,N,'hist','FaceColor','flat');
hold on
for n = 1:length(N)
if (x - x/1.09) - (x-1) > 0
probability(n) = 1 - ((x-x/1.09) - (x-1))/((x - 1/1.09)+(x/0.91 - x));
else
probability(n) = 1;
end
color_num = 30;
cm = jet(color_num);
min = 0.5450;
max = 1;
color_map_index = floor(1 + (probability(n) - min)/(max-min)*(color_num-1));
rbg = cm(color_map_index,:);
h.CData(n,:) = rbg;
end
Similar to the MATLAB example, I first create my bar graph. Next, I want to loop through and prescribe the color for each bar based on a calculation. I do this by creating a colormap with # of bins and a min/max, getting a color index, then finally retrieving the rbg value. I get the following error when I try to apply the color:
Subscript indices must either be real positive integers or logicals.
h.CData(n,:) = rbg;
If I dive into the h object, MATLAB tells me that CData has a size of (4x65). What's going on here? Both new_edge and N are 1x65 vectors.
Are you certain that the error you're getting ("Subscript indices must either be real positive integers or logicals") is coming from the following line?:
h.CData(n,:) = rbg;
Since we know n is a positive integer greater than or equal to one, the indexing here shouldn't have a problem. It's more likely that your error is coming from the line above it (i.e. the value for color_map_index is less than 1). I would double-check how you are computing color_map_index.
You could also try using function notation (i.e. get and set) instead of dot notation to update the property:
cData = get(h, 'CData');
cData(n, :) = rbg;
set(h, 'CData', cData);
Incidentally, you should also not be giving your variables the same name as existing functions, like you are doing here:
...
min = 0.5450;
max = 1;
...
This shadows the built-in min and max functions, which can also lead to the same error message under other conditions. Definitely rename those.
If you are still having trouble after trying those fixes, you could try setting the color using indexed color mapping instead, as illustrated in one of my other answers (near the bottom). As a simple example, the following plots 20 bars of 30 different possible values, then colors them based on their height:
color_num = 30;
N = randi(color_num, 1, 20);
hBar = bar(N, 'hist');
colormap(parula(color_num));
set(hBar, 'CData', N, 'CDataMapping', 'direct');
And the plot:
This could be a problem with your Matlab version.
When I test CData with bar on 2017b, this works:
openExample('graphics/ControlIndividualBarColorsExample')
When I try it on 2017a, it doesn't run.
Does the example work?
Given that this is a version control problem, there's really not a clean solution. In case anyone else comes along with a similar question and has the same version, here's a workaround that worked for me in 2017a.
Rather than creating a bar chart, you can simply draw rectangles. It's messy, but it does produce the desired result.
[N,edges] = histcounts(AB(AB<2));
probability = zeros(1,length(N));
new_edge = zeros(1,length(N));
for m = 1:length(N)
new_edge(m) = (edges(m) + edges(m+1))/2;
end
figure
hold on
for n = 1:length(N)
x = new_edge(n);
if ((x - x/1.09) - (x-1)) > 0
probability(n) = 1 - ((x-x/1.09) - (x-1))./((x - x/1.09)+(x/0.91 - x));
else
probability(n) = 1;
end
color_num = 100;
cm = jet(color_num);
min = 0;
max = 1;
color_map_index(n) = floor(1 + (probability(n) - min)/(max-min)*(color_num-1));
rbg = cm(color_map_index(n),:);
rectangle('Position',[edges(n),0,(edges(n+1)-edges(n)),N(n)],'Edgecolor','k','FaceColor',rbg)
end
set(gcf,'color','w');
blah = colorbar;

vector comparison and new assignment

I'd like to ask you question about some matlab code I wrote, But first of all tell you my problem. I have 2 vectors, Test Labels and Predicted labels and I want to compare them for classification reasons. Further more I want to allocate some labels new. so I have something like this 111121111 = 1 or 1122222222 =2 which I want to achieve. My code is
y = [];
for k = 10:length(predictedLabel)-10
y = [y; newlabel(predictedLabel, k, 5)];
end
and the function newlabel is
function [nl] = newlabel(x, n, L)
numClasses = 3;
x1 = x(n-L:n+L);
c = zeros(numClasses, 1);
for k=1:length(x1)
c(x1(k)) = c(x1(k))+1;
end
[~,nl]=max(c);
end
My problem is now that I result following vector lengths
predictedLabel = 4996*1;
k=4986*1;
y=4977*1;
and I can't see my mistake
Any help is appreciated even new ideas with probability estimations
Thanks
loop
1- when using the length function on a scalar value it gives 1 then the value inside the for loop becomes from 10:1-10 which is meaningless. (If you want to use decreasing step you should provide something like this 10:-1:1).
2- if you want to make a vector with the size of 4996x1 it would be like this : zeros(4996,1) or ones(4996,1) or sth like this.
3- tell us about your desired result and your error.... the description is not obvious to me.

MATLAB travelling grids

I want to built a "travelling grid" MATLAB. Actually, I had to choose another MATLAB command instead of linspace to built my grid for any k. Is it possible with a MATLAB command?
for k=1:5
a=0;
b(k)=k.*3;
x=linspace(0,b(k),10);
y=linspace(0,30,10);
for z=1:length(x)
for t=1:length(y)
A(z,t,k)=x(z).*exp(-y(t));
end
end
end
Thanks for any help,
X = linspace(0,3,10);
XX(1,:,:) = bsxfun(#times,X,(1:5)')';
Y = exp(-linspace(0,30,10));
B = bsxfun(#times,Y',XX);
B = permute(B,[2,1,3]);
Your current code is working fine, so I'm not sure what the question is... Here is a slightly simpler implementation:
b = (1:5).*3;
A = zeros(10,10,5);
for k=1:5
[X,Y] = ndgrid(linspace(0,b(k),10), linspace(0,30,10));
A(:,:,k) = X.*exp(-Y);
end
If you also want the y-limits to change as well, the process is similar; you would have two loops and the result A being a 4D matrix

Binning in matlab

I have been unable to find a function in matlab or octave to do what I want.
I have a matrix m of two columns (x and y values). I know that I can extract the column by doing m(:,1) or m(:,2). I want to split it into smaller matricies of [potentially] equal size and and plot the mean of these matricies. In other words, I want to put the values into bins based on the x values, then find means of the bins. I feel like the hist function should help me, but it doesn't seem to.
Does anyone know of a built-in function to do something like this?
edit
I had intended to mention that I looked at hist and couldn't get it to do what I wanted, but it must have slipped my mind.
Example: Let's say I have the following (I'm trying this in octave, but afaik it works in matlab):
x=1:20;
y=[1:10,10:1];
m=[x, y];
If I want 10 bins, I would like m to be split into:
m1=[1:2, 1:2]
...
m5=[9:10, 9:10]
m6=[10:11, 10:-1:9]
...
m10=[19:20, 2:-1:1]
and then get the mean of each bin.
Update: I have posted a follow-up question here. I would greatly appreciate responses.
I have answered this in video form on my blog:
http://blogs.mathworks.com/videos/2009/01/07/binning-data-in-matlab/
Here is the code:
m = rand(10,2); %Generate data
x = m(:,1); %split into x and y
y = m(:,2);
topEdge = 1; % define limits
botEdge = 0; % define limits
numBins = 2; % define number of bins
binEdges = linspace(botEdge, topEdge, numBins+1);
[h,whichBin] = histc(x, binEdges);
for i = 1:numBins
flagBinMembers = (whichBin == i);
binMembers = y(flagBinMembers);
binMean(i) = mean(binMembers);
end