scatter plot with its own ID - matlab

i am trying to plot data labels in a scatterplot.
For example i have vector
X=[0,1,2,3,4,2,1,0];
Y=[0,9,2,6,2,1,1,0];
z = 1:size(X,2);
scatter (X,Y)
i am using
for A = 1:size(X,2);
text(X(A),Y(A),z(A));
end;
however MATLAB state that Error using ==> text String argument expected after 2 or 3 numeric arguments
What should i do to add the ID in each pairs of x and y and also how to display the ID that has the same value of X and Y.
Thanks a lot in advance.

Change z(A) to num2str(z(A)), since text() expects it to be a string.

Related

Why Matlab2tikz can't show figures with categorial data?

I plotted a bubble chart using scatter plot in Matlab with text lables on x axis and integer numbers on y axis. The bubble sizes are also considered as integer numbers. I included both code and figure of my chart. When I try to transform the figure to tikz using "matlab2tikz" library, I see the following error:
"Error using categorical/cat (line 69): Can not concatenate a double array and a categorical array".
I don't have any double numbers in my values. How can I transform this figure to tikz format?
x = ["C","A", "P", "K"]; %x lables
x1=categorical(x);
y = [33,68,200,14];% values
y1 = [48,177,200,16];
y2=[6,6,200,3];
sz = [35,7, 10, 56];%Bubble sizes
sz1=[25,7, 30, 53];
sz2=[44, 8,4,10];
scatter(x1,y,sz,'g','LineWidth',2);
hold on
scatter(x1,y1,sz1,'b','LineWidth',2);
hold on
scatter(x1,y2,sz2,'r','LineWidth',2);
hold off
legend({'y = Method1','y = Method2', 'y = Method3'},'Location','north');
title('NewModel');
ylabel('%Value');
saveas(gcf,'test.png');
You do have double numbers. y, y1 and y2 are double whereas x1 is categorical which is why you are getting that error.
For your case, the error can be fixed by changing the square brackets to curly brackets in line 4052. i.e. change:
data = [xData(:), yData(:)]; %line 4052 of matlab2tikz.m
to:
data = {xData(:), yData(:)};
The reason is what the error message says. You have categorical xData and double yData. These cannot be concatenated into a regular array. A cell array is for combining different types of data.
Similarly,
data=applyHgTransform(m2t,[xData(:), yData(:), zData(:)]); %line 4056 of matlab2tikz.m
should be modified to the following if you are plotting in 3D and have mixed data type:
data=applyHgTransform(m2t,{xData(:), yData(:), zData(:)});

How to set X-axis units to datetime of empty plot in Matlab?

I have created figure with figure; and didn't plot anything on it.
How can I set it's x-axis to be datetime from this situation?
Entering
xlim([startTime, endTime]);
causes
Limits must be a 2-element vector of increasing numeric values.
How to accomplish?
Since the xlim function accepts a vector of two numeric values (the first one being the minimum and the second one representing the maximum), you can convert your datetime values into the required numeric values by using the datenum function. For example:
xlim([datenum(startTime) datenum(endTime)]);
In order to make your x-axis readable, you can make a call to datetick in order to convert the tick labels back to a valid datetime format. For example:
datetick('x','dd-mm-yyyy');
Here is a very basic example:
date_beg = datetime(2016,01,01);
date_end = datetime(2017,12,31);
date_seq = date_beg:date_end;
x = datenum(date_seq);
y = 1:numel(date_seq);
plot(x,y);
datetick('x','dd-mm-yyyy');
If you want to preserve the x-axis limits, call the datetick function passing the keeplimits argument. Here is a code snippet that reproduces your attempt:
date_beg = datetime(2016,01,01);
date_end = datetime(2017,09,15);
figure();
xlim([datenum(date_beg) datenum(date_end)]);
datetick('x','dd-mm-yyyy','keeplimits');

Interpolating data fails: grid vectors do not define a grid of points that match the given values

I have some time/frequency data and I try to interpolate it using the interp2 function of Matlab. The data [F,T,data] is obtained from a different Matlab routine of Matlab, spectrogram in case you are interested.
[~,F,T,data] = spectrogram(...)
data = 10*log10(data);
I can plot the data using surf. The data is fine, I believe. However interpolating the data seems to be a problem. Even using interp2(F,T,data,F,T) (so actually no interpolating) gives the error below.
What is going wrong here?
I have the data which I use here: https://www.dropbox.com/s/zr5zpfhp6qyarzw/test.mat
interp2(F,T,data,f,t)
Error using griddedInterpolant
The grid vectors do not define a grid of points that match the given values.
Error in interp2>makegriddedinterp (line 228)
F = griddedInterpolant(varargin{:});
Error in interp2 (line 128)
F = makegriddedinterp({X, Y}, V, method,extrap);
>> size(F),size(T),size(data),size(f),size(t)
ans =
129 1
ans =
1 52
ans =
129 52
ans =
200 1
ans =
1 121
The problem is that you should swap F and T:
interp2(T,F,data,t,f);
The first argument corresponds with the columns of the matrix and the second argument with the rows as documented here:
If X and Y are grid vectors, then V must be a matrix containing
length(Y) rows and length(X) columns.
As an alternative, you may take the transpose of data:
interp2(F,T,data',f,t);
Reasoning behind (strange) argument order
interp2(X,Y,V,Xq,Yq) is interpreted as the interpolation of a function, represented by the matrix V, i.e. the sample values. The problem is that the arguments/indexes of a function/matrix are rather supplied in an opposite order:
matrix(row, column)
versus
function(x,y)
x (first argument) often represents the horizontal axes and therefore corresponds with the column (second argument) argument and idem for y and row.

Mapping a column related by unique values to all values in another matrix

I have a matrix of drill hole positions ([X Y]). I have extracted the unique positions ([Xuq Yuq]) and then interpolated an elevation (Z) for each using griddata. Now I want to create a column in the original matrix with the relevant Z assigned back to every X & Y position. Is this possible without for loops?
If you created your unique positions and the elevation by doing something like:
XY = unique(data(:,[1 2]),'rows');
Z = f(XY); % some function of XY(:,1) and XY(:,2)
Then all you need to do is keep the third output value from unique and use that to map Z back in appropriately:
[XY,~,ic] = unique(data(:,[1 2]),'rows');
Z = f(XY);
data = [data Z(ic)]; % append the mapped column

4D plot display variables with data cursor Matlab

I am having trouble figuring out how display 4 variables in my plot.
I want to vary the independent variables X,V, to produce the dependent variables Y and Z.
Y is a function of X AND V. And Z is a function of Y AND X.
This may be easier to see the dependencies: X, V, Y(X,V), Z(X,Y(X,V)).
I have used the surf function to plot X,Y,Z, but I also want to know the values of V, which I cannot currently ascertain.
Here is some test data to illustrate:
X = linspace(1,5,5)
V = linspace(1,5,5)
Capture = []
for j = 1:length(V)
Y = X.*V(j)
Capture = [Capture;Y]
end
[X,V] = meshgrid(X,V);
Z = Capture.*X
surf(X,Y,Z)
If I use the data cursor, I can see values of X,Y,Z, but I would also like to know the values of V. I know that the way I have it set up is correct because if I make two plots, say:
surf(X,Y,Z)
surf(X,V,Z)
and then use the data cursor to go on the same point of X and Z for both graphs the values for V and Y are what they should be for that point (X,Z).
Is there anyway to show the values for X,Y,V and Z without having to generate two separate graphs?
Thanks!
Using color as your 4th dimension is a possibility (whether it looks good to you is a matter of taste).
surf(X,Y,Z,V); #% 4th arg (V) is mapped onto the current colormap
You can change the colormap to suit your tastes.
colorbar #% displays a colorbar legend showing the value-color mapping
Edit: The questioner wants to see exactly the data in the not-shown array, rather than just a color. This is a job for custom data cursor function. Below I've implemented this using purely anonymous functions; doing it within a function file would be slightly more straightforward.
#% Step 0: create a function to index into an array...
#% returned by 'get' all in one step
#% The find(ismember... bit is so it returns an empty matrix...
#% if the index is out of bounds (if/else statements don't work...
#% in anonymous functions)
getel = #(x,i) x(find(ismember(1:numel(x),i)));
#% Step 1: create a custom data cursor function that takes...
#% the additional matrix as a parameter
myfunc = #(obj,event_obj,data) {...
['X: ' num2str(getel(get(event_obj,'position'),1))],...
['Y: ' num2str(getel(get(event_obj,'position'),2))],...
['Z: ' num2str(getel(get(event_obj,'position'),3))],...
['V: ' num2str(getel(data,get(event_obj,'dataindex')))] };
#% Step 2: get a handle to the datacursormode object for the figure
dcm_obj = datacursormode(gcf);
#% Step 3: enable the object
set(dcm_obj,'enable','on')
#% Step 4: set the custom function as the updatefcn, and give it the extra...
#% data to be displayed
set(dcm_obj,'UpdateFcn',{myfunc,V})
Now the tooltip should display the extra data. Note that if you change the data in the plot, you'll need to repeat Step 4 to pass the new data into the function.