I've found some solutions with cells but none with Numberarrays.
The Problem is simple, I have one Array a=(0,1,2,3,4,5,6,7) and I want to change every other value with "blankspace" like this a=(0,'',2,''...) so that the array stays the same length but has only every other value.
When I try something like this a(2:2:end)='';
I get a=(0,2,4,6) the length is not the same.
When I try a(2:2:end)=blanks(1);
It almost works :), but not exactly, I get a=(0,'32',2,'32',4,'32'...)
I know that actually 32 means 'space' (ASCII) what actually means it works properly. I then try to use this to set my TickLabels but it interprets it like 32 not like ASCII.
You can't introduce a space as an entry in a number array. You can only introduce numbers.
If you want that for using it as tick labels, convert to a cell array and then you can set some cells' contents to [] (empty):
a = [0 1 2 3 4 5 6 7]; % original vector
a = num2cell(a); % convert to cell
a(2:2:end) = {[]}; % set some cells' contents to []
x = 1:8; % x data for example plot
y = x.^2; % y data for example plot
plot(x, y) % x plot the graph
set(gca, 'xticklabels', a) % set x tick labels
To get tick labels without scientific notation use num2str with the appropriate format:
a = [0 1 2 3 4 5 6 7]*1e6; % original vector
a = num2cell(a); % convert to cell
a(2:2:end) = {[]}; % set some cells' contents to []
a = cellfun(#num2str, a, 'Uniformoutput', false); % convert each number to a string
x = [0 1 2 3 4 5 6 7]*1e6; % x data for example plot
y = x.^2; % y data for example plot
plot(x, y) % x plot the graph
set(gca, 'xticklabels', a) % set x tick labels
Related
I have code and the result as below:
%% How to plot each matrix in a cell in 3d plot(1 matrix with 1 color) ?
% Generate Sample data cell A(1x10 cell array)
clear; clc;
A = cell(1,10); % cell A(1x10 cell array)
for kk = 1:numel(A)
z = 10*rand()+(0:pi/50:10*rand()*pi)';
x = 10*rand()*sin(z);
y = 10*rand()*cos(z);
A{kk} = [x,y,z];
end
A_6 = A(1:6); % generate a cell with the first 6 matrices in "A" cell array
% The numer "6" can be changed to be any number which you want to plot them by colormap
newA = vertcat(A_6{:}); %Concatenating all matrices inside A vertically
numcolors = numel(A_6); %Number of matrices equals number of colors
colourRGB = hsv(numcolors); %Generating colours to be used using hsv colormap
colourtimes = cellfun(#(x) size(x,1),A_6);%Determining num of times each colour will be used
colourind = zeros(size(newA,1),1); %Zero matrix with length equals num of points
colourind([1 cumsum(colourtimes(1:end-1))+1]) = 1;
colourind = cumsum(colourind); %Linear indices of colours for newA
scatter3(newA(:,1), newA(:,2), newA(:,3), [], colourRGB(colourind,:),'filled');
%if you want to specify the size of the circles, use the following line instead:
% scatter3(newA(:,1), newA(:,2), newA(:,3), colourind , colourRGB(colourind,:),'filled');
grid on;
view(3); %view in 3d plane
colormap(colourRGB); %using the custom colormap of the colors we used
%Adjusting the position of the colorbar ticks
caxis([1 numcolors]);
colorbar('YTick',[1+0.5*(numcolors-1)/numcolors:(numcolors-1)/numcolors:numcolors],'YTickLabel', num2str([1:numcolors]'), 'YLim', [1 numcolors]);
I have the image like this:
How can I shown "YTickLabel" with some specified value (not show all) as below figure?
Taking the code from your comment to the previous answer:
h = colorbar('YTick',[1:numcolors],'YTickLabel', num2str([1:numcolors]'), 'YLim', [1 numcolors]); set(h, 'Ticklabels', {1 [] 3 [] 5 6}); set(h, 'Ticks', {1 3 5 6});
You are now setting 6 tick labels for only 4 ticks. If set the ticks to the correct values, then the auto-generated tick labels will be what you want.
Try the following:
h = colorbar('YTick',[1:numcolors],'YTickLabel', num2str([1:numcolors]'), 'YLim', [1 numcolors]);
set(h, 'Ticks', {1 3 5 6});
To remove some ticks with their labels, just set the 'YTick' property of the colorbar accordingly. That is, replace your last line by something like:
colorbar('YTick', [1 3 5 6], 'YLim', [1 numcolors])
Assume you have 1000 indexed datapoints, with two labels grouped into region1 and region2. Here is an example of how to generate such random data
indices = 1:1000;
data = zeros(size(indices));
% some regions of data
region1 = [50:100 200:340 450:500 670:980];
region2 = setdiff(indices, region1);
% generating random data
data(region1) = rand(size(region1)) + 1;
data(region2) = rand(size(region2));
Now, if I plot these two regions I get a plot shown below
The code to generate the plot
% plotting
figure(1);
cla(gca);
hold on;
plot(region1, data(region1));
plot(region2, data(region2));
hold off;
Now the question: Is there an elegant way of removing the connecting lines between the disconnected data regions, without doing much data manipulation? I still want to use the solid line linestyle, or have a look similar to that.
If you make the x or y values into NaN then they wont be plotted. Since you have two complimentary regions, you can use them to set values to NaN...
% Two vectors which each cover ALL elements in "data", but with NaN where
% the other region is to be plotted. As per example, indices=1:1000;
r1 = 1:1000; r1(region2) = NaN;
r2 = 1:1000; r2(region1) = NaN;
% Plot all data for both lines, but NaNs wont show.
figure(1); clf;
hold on;
plot(r1, data);
plot(r2, data);
hold off;
Output:
Turns out if you represent regions as a vector of the same length as x and y with integer values representing the index of the region (e.g. regions = [1 1 1 2 2 1 1 1 ..]), there is an elegant one-linear that does the job for an arbitrary number of regions. Here is an example
% Generating test data
x = 1:1000;
y = sin(x/100) + rand(1, 1000);
regions = repelem([1 2 3 1 2 3 1 2 3 3], repelem(100, 10)); % a [1 x 1000] vector
% Plotting
plot(bsxfun(#rdivide, x(:), bsxfun(#eq, regions(:), unique(regions(:))')), y(:));
Here, I am building the matrix for x with values that should not be plotted being Inf, due to the #rdivide division by 0. The result is the following.
I hope this will be helpful for someone in the future.
I need to plot a cell array with the following format in Matlab:
{[vector1], [vector2], ...}
Into a 2D graph with the index of the vector as the y and the vector as the x
([vector1], 1), ([vector2], 2), ...
Here's a simple option:
% some arbitrary data:
CellData = {rand(10,1)*50,rand(10,1)*50,rand(10,1)*50};
% Define x and y:
x = cell2mat(CellData);
y = ones(size(x,1),1)*(1:size(x,2));
% plot:
plot(x,y,'o')
ylim([0 size(x,2)+1])
so you plot each vector of x on a separate y value:
It will work as long as your cell array is just a list of vectors.
EDIT: For non equal vectors
You'll have to use a for loop with hold:
% some arbitrary data:
CellData = {rand(5,1)*50,rand(6,1)*50,rand(7,1)*50,rand(8,1)*50,rand(9,1)*50};
figure;
hold on
for ii = 1:length(CellData)
x = CellData{ii};
y = ones(size(x,1),1)*ii;
plot(x,y,'o')
end
ylim([0 ii+1])
hold off
Hope this answers your question ;)
Here's my (brute force) interpretation of your request. There are likely more elegant solutions.
This code generates a dot plot that puts the values from the vectors at each index on the y axis—bottom to top. It can accommodate vectors of different lengths. You could make it a dot plot of vector distributions, but you might need to add some jitter to the x value, if multiple occurrences of identical or nearly identical values are possible.
% random data--three vectors from range 1:10 of different lengths
for i = 1:3
dataVals{i} = randi(10,randi(10,1),1);
end
dotSize = 14;
% plot the first vector with dots and increase the dot size
% I happen to like filled circles for this, and this is how I do it.
h = plot(dataVals{1}, ones(length(dataVals{1}), 1),'.r');
set(h,'markers', dotSize);
ax = gca;
axis([0 11 0 4]); % set axis limits
% set the Y axis labels to whole numbers
ax.YTickLabel = {'','','1','','2','','3','','',}';
hold on;
% plot the rest of the vectors
for i=2:length(dataVals)
h = plot(dataVals{i}, ones(length(dataVals{i}),1)*i,'.r');
set(h, 'markers', dotSize);
end
hold off
Without any data this is the best I can come up with for what you want:
yourCell = {[0,0,0],[1,1,1],[2,2,2]}; % 1x3 cell
figure;
plot(cell2mat(yourCell));
ylabel('Vector Values');
xlabel('Index of Vector');
It makes a plot like this:
Hope this helps.
I have a data set that looks like this
140400 70.7850 1
140401 70.7923 2
140402 70.7993 3
140403 70.8067 4
140404 70.8139 5
140405 70.8212 3
Where the first column corresponds to time (one second intervals between data points) and will be on the x axis, the second column corresponds with distance and will be on the y axis. The third column is a number (one through five) that is a qualification of the movement.
I want to make a plot that changes the color of the line between two points depending on what the number of the previous data point was. For example, I want the line to be red between the first and second data points because the qualification value was 1.
I've seen a lot of posts about making a sliding scale of colors depending on an intensity value, but I just want 5 colors: (red, orange, yellow, green, and blue) respectively.
I tried doing something like this:
plot(x,y,{'r','o','y','g','b'})
But with no luck.
Any ideas of how to approach this? Without looping if possible.
You can also do it with a trick which works with Matlab version anterior to 2014b (as far back as 2009a at least).
However, is will never be as simple as you expected (unless you write a wrapper for one of the solution here you can forget about plot(x,y,{'r','o','y','g','b'})).
The trick is to use a surface instead of a line object. Surfaces benefit from their CData properties and a lot of useful features to exploit color maps and texture.
Matlab surf does not handle 1D data, it needs a matrix as input so we are going to give it by just duplicating each coordinate set (for example xx=[x,x]).
Don't worry though, the surface will stay as thin as a line, so the end result is not ugly.
%% // your data
M=[140400 70.7850 1
140401 70.7923 2
140402 70.7993 3
140403 70.8067 4
140404 70.8139 5
140405 70.8212 3];
x = M(:,1) ; %// extract "X" column
y = M(:,2) ; %// same for "Y"
c = M(:,3) ; %// extract color index for the custom colormap
%% // define your custom colormap
custom_colormap = [
1 0 0 ; ... %// red
1 .5 0 ; ... %// orange
1 1 0 ; ... %// yellow
0 1 0 ; ... %// green
0 0 1 ; ... %// blue
] ;
%% // Prepare matrix data
xx=[x x]; %// create a 2D matrix based on "X" column
yy=[y y]; %// same for Y
zz=zeros(size(xx)); %// everything in the Z=0 plane
cc =[c c] ; %// matrix for "CData"
%// draw the surface (actually a line)
hs=surf(xx,yy,zz,cc,'EdgeColor','interp','FaceColor','none','Marker','o') ;
colormap(custom_colormap) ; %// assign the colormap
shading flat %// so each line segment has a plain color
view(2) %// view(0,90) %// set view in X-Y plane
colorbar
will get you:
As an example of a more general case:
x=linspace(0,2*pi);
y=sin(x) ;
xx=[x;x];
yy=[y;y];
zz=zeros(size(xx));
hs=surf(xx,yy,zz,yy,'EdgeColor','interp') %// color binded to "y" values
colormap('hsv')
view(2) %// view(0,90)
will give you a sine wave with the color associated to the y value:
Do you have Matlab R2014b or higher?
Then you could use some undocumented features introduced by Yair Altman:
n = 100;
x = linspace(-10,10,n); y = x.^2;
p = plot(x,y,'r', 'LineWidth',5);
%// modified jet-colormap
cd = [uint8(jet(n)*255) uint8(ones(n,1))].' %'
drawnow
set(p.Edge, 'ColorBinding','interpolated', 'ColorData',cd)
My desired effect was achieved below (simplified):
indices(1).index = find( data( 1 : end - 1, 3) == 1);
indices(1).color = [1 0 0];
indices(2).index = find( data( 1 : end - 1, 3) == 2 | ...
data( 1 : end - 1, 3) == 3);
indices(2).color = [1 1 0];
indices(3).index = find( data( 1 : end - 1, 3) == 4 | ...
data( 1 : end - 1, 3) == 5);
indices(3).color = [0 1 0];
indices(4).index = find( data( 1 : end - 1, 3) == 10);
indices(4).color = [0 0 0];
indices(5).index = find( data( 1 : end - 1, 3) == 15);
indices(5).color = [0 0 1];
% Loop through the locations of the values and plot their data points
% together (This will save time vs. plotting each line segment
% individually.)
for iii = 1 : size(indices,2)
% Store locations of the value we are looking to plot
curindex = indices(iii).index;
% Get color that corresponds to that value
color = indices(iii).color;
% Create X and Y that will go into plot, This will make the line
% segment from P1 to P2 have the color that corresponds with P1
x = [data(curindex, 1), data(curindex + 1, 1)]';
y = [data(curindex, 2), data(curindex + 1, 2)]';
% Plot the line segments
hold on
plot(x,y,'Color',color,'LineWidth',lineWidth1)
end
When the result figure of two variables plotted is a circle, will be necessary to add the time in z axes.
For example the figure of induction machine rotor velocity vs electric torque in one laboratory test is: 2d plot figure
In the last figure the direction of the time point plotting could be clockwise or counter clockwise. For the last reason will be added time in z axis.
% Wr vs Te
x = logsout.getElement( 'Wr' ).Values.Data;
y = logsout.getElement( '<Te>' ).Values.Data;
z = logsout.getElement( '<Te>' ).Values.Time;
% % adapt variables for use surf function
xx = zeros( length( x ) ,2 );
yy = zeros( length( y ) ,2 );
zz = zeros( length( z ) ,2 );
xx (:,1) = x; xx (:,2) = x;
yy (:,1) = y; yy (:,2) = y;
zz (:,1) = z; zz (:,2) = z;
% % figure(1) 2D plot
figure (1)
hs = surf(xx,yy,zz,yy,'EdgeColor','interp') %// color binded to "y" values
colormap('hsv')
view(2)
% %
figure(2)
hs = surf(xx,yy,zz,yy,'EdgeColor','interp') %// color binded to "y" values
colormap('hsv')
view(3)
Finally we can view the 3d form and detect that counterwise is the real direction of the time plotting is: 3d plot
Scatter can plot the color according to the value and shows the colormap of the range of values. It's hard to interpolate the color though if you want continuous curves.
Try:
figure
i = 1:20;
t = 1:20;
c = rand(1, 20) * 10;
scatter(i, t, [], c, 's', 'filled')
colormap(jet)
The figure looks like
I'm trying to plot bar chart for input data and to add data labels on each bar, when I run the program I got an error as "Undefined function 'max' for input arguments of type 'cell'." my code is...
data = [3 6 2 ;9 5 1];
figure; %// Create new figure
h = bar(data); %// Create bar plot
%// Get the data for all the bars that were plotted
x = get(h,'XData');
y = get(h,'YData');
ygap = 0.1; %// Specify vertical gap between the bar and label
ylim([0 12])
ylimits = get(gca,'YLim');
%// The following two lines have minor tweaks from the original answer
set(gca,'YLim',[ylimits(1),ylimits(2)+0.2*max(y)]);
labels = cellstr(num2str(data')) %//'
for i = 1:length(x) %// Loop over each bar
xpos = x(i); %// Set x position for the text label
ypos = y(i) + ygap; %// Set y position, including gap
htext = text(xpos,ypos,labels{i}); %// Add text label
set(htext,'VerticalAlignment','bottom', 'HorizontalAlignment','center')
end
when I give input as "data = [3 6 2 9 5 1]", the program runs fine
Matlab is a typeless language, so you don't know what type y is actually going to be. When you try data = [3 6 2 9 5 1] and call class(y) you will get double as an answer, which in this example is a vector of real numbers max() can work on.
However when you use data = [3 6 2 ; 9 5 1], you get different y :
>> class(y)
ans =
cell
>> y
y =
[1x2 double]
[1x2 double]
[1x2 double]
>>
Which means y is not a vector nor a matrix but a cell array that holds together three double vectors. max() does not know how to work on cell arrays and gives you
Undefined function 'max' for input arguments of type cell
error . You can find more on Matlab data types on http://www.mathworks.com/help/matlab/data-types_data-types.html
You can fix this error by turning y back into a vector, but as your labels will also change I will leave you here:
data = [3 6 2 ;9 5 1];
figure; %// Create new figure
h = bar(data); %// Create bar plot
%// Get the data for all the bars that were plotted
x = get(h,'XData');
y = get(h,'YData');
ygap = 0.1; %// Specify vertical gap between the bar and label
ylim([0 12])
ylimits = get(gca,'YLim');
y=[y{1} y{2} y{3}]; %works in this particular example
%// The following two lines have minor tweaks from the original answer
set(gca,'YLim',[ylimits(1),ylimits(2)+0.2*max(y)]);
labels = cellstr(num2str(data'))