Matlab - Get (x,y) value of a plot by clicking on it - matlab

Matlab has the ginput for getting the (x,y) value of where you have clicked on the graph. However, say that I have plotted a graph with plot(t, sin(2*pi*t)). I want to be able to have the cursor move on the actual plot, and by clicking it, I get the (x,y) coordinate of my plot (in this case, the time and the value of sine).
Is this possible?

When the MATLAB figure is open, you can use the data cursor tool to help you traverse through the plot.
Here's a quick example:
t = 0 : 0.01 : 10;
plot(t, sin(t));
Here's what your plot looks like, and I have highlighted the option of where you can click for the data cursor tool.
Once you click on the data cursor option, click anywhere on the plot and it'll give you a data cursor tip. At that point you selected, it shows the x and y co-ordinate. In your case, x denotes time and y denotes amplitude.
Once you have a data cursor tip there, click on it (the black square) and drag it along the curve. You will see that the data cursor tip updates and moves along the curve. Judging from your question, I believe this is what you're looking for.
Take note that the data cursor tip only works for the points that you have plotted. It does not interpolate in between the points. As such, if you want finer resolution, choose a smaller step size between the beginning and end points.
Also, if you want to know the exact index of where your point is, plot just the amplitude values themselves:
plot(sin(t));
The x axis will plot the index number of each point instead of the time values. You can then use the data cursor tip to locate which index you want, then do that indexing that you have specified in your comment above. In other words:
This is telling us that at index 304, it gives us a y value of 0.1114. Then you could do t(304) to find the actual time value where the amplitude was at 0.1114.

h = plot(t, sin(2*pi*t)); %// get a handle to the graph
[x, ~] = ginput(1); %// y from ginput not wanted; it will be read from the graph
y = interp1(get(h,'XData'), get(h,'YData'), x); %// interpolate the graph for y

Related

How to change font size of right axis of Pareto plot in Matlab

I am trying to bold the right side y axis for a Pareto plot in Matlab, but I can not get it to work. Does anyone have any suggestions? When I try to change the second dimension of ax, I get an error:
"Index exceeds matrix dimensions.
Error in pcaCluster (line 66)
set(ax(2),'Linewidth',2.0);"
figure()
ax=gca();
h1=pareto(ax,explained,X);
xlabel('Principal Component','fontweight','b','fontsize',20)
ylabel('Variance Explained (%)','fontweight','b','fontsize',20)
set(ax(1),'Linewidth',2.0);
set(ax(1),'fontsize',18,'fontweight','b');
%set(ax(2),'Linewidth',2.0);
%set(ax(2),'fontsize',18,'fontweight','b');
set(h1,'LineWidth',2)
Actually you need to add an output argument during the call to pareto and you will then get 2 handles (the line and the bar series) as well as 2 axes. You want to get the YTickLabel property of the 2nd axes obtained. So I suspect that in your call to pareto above you do not need to supply the ax argument.
Example:
[handlesPareto, axesPareto] = pareto(explained,X);
Now if you use this command:
RightYLabels = get(axesPareto(2),'YTickLabel')
you get the following (or something similar):
RightYLabels =
'0%'
'14%'
'29%'
'43%'
'58%'
'72%'
'87%'
'100%'
What you can do is actually to erase them altogether and replace them with text annotations, which you can customize as you like. See here for a nice demonstration.
Applied to your problem (with dummy values from the function docs), here is what you can do:
clear
clc
close all
y = [90,75,30,60,5,40,40,5];
figure
[hPareto, axesPareto] = pareto(y);
%// Get the poisition of YTicks and the YTickLabels of the right y-axis.
yticks = get(axesPareto(2),'YTick')
RightYLabels = cellstr(get(axesPareto(2),'YTickLabel'))
%// You need the xlim, i.e. the x limits of the axes. YTicklabels are displayed at the end of the axis.
xl = xlim;
%// Remove current YTickLabels to replace them.
set(axesPareto(2),'YTickLabel',[])
%// Add new labels, in bold font.
for k = 1:numel(RightYLabels)
BoldLabels(k) = text(xl(2)+.1,yticks(k),RightYLabels(k),'FontWeight','bold','FontSize',18);
end
xlabel('Principal Component','fontweight','b','fontsize',20)
ylabel('Variance Explained (%)','fontweight','b','fontsize',20)
which gives this:
You can of course customize everything you want like this.
That is because ax is a handle to the (first/left) axes object. It is a single value and with ax(1) you got lucky, its ax again, but ax(2) is simply not valid.
I suggest to read the docs about how to get the second axis. Another good idea always is to open the plot in the plot browser, click whatever object you want so it is selected and then get its handle by typing gco (get current object) in the command window. You can then use it with set(gco, ...).

horizontally shift starting point for stem() in MatLab

I have a sequence with data and an offset. I'm asked to plot a stem() graph of the data, starting at the offset. I have figured out the data part (the easy part) and how to change the window to include the offset, but when I plot the graph, it shows the offset with a value of zero and zeros until 1 where the sequence.data will start and plot points.
methods
function s = sequence(data, offset)
s.data = data;
s.offset = offset;
end
function stem(x)
% STEM Display a Matlab sequence, x, using a stem plot.
stem(x.offset,x.data);
axis([x.offset x.offset+length(x.data) 'auto' 'auto']);
end
I need to figure out how to "move" my x.data to my x.offset and start stem plotting there.
I don't understand why you simply can't add an x offset while keeping the y data the same?
For instance, given your example in your comments above:
x = 0:4;
y = 1:5;
This is what the original graph looks like, as well as shifting the graph to the left by 3 (-3):
stem(x,y,'b');
hold on;
stem(x-3,y,'r');
This is what I get:
The blue data is the original, while the red is the shifted instance to the left by 3. As you can see, the y data is the same, but the x points move to the left by 3. What your code is actually doing is that it does not shift the actual data. You are only changing the display range of your stem plot. As such, you should really be doing this:
methods
function s = sequence(data, offset)
s.data = data;
s.offset = offset;
end
function stem(x)
% STEM Display a Matlab sequence, x, using a stem plot.
%// First define sequence from [0,N-1]
vals = 0:numel(x.data)-1;
%// Now use the above and manually shift the x coordinate
stem(vals+x.offset,x.data);
end
I'm going to assume that your data on the x-axis starts counting at 0, and so we will declare a sequence from 0 up to N-1 where N is the total number of elements that you have. Once we declare this sequence, when it's time to draw the stem plot, we simply add an offset to this sequence and use this as the x data. The y data should stay the same.
However, I would argue that creating a custom class for implementing this addition to stem is less readable than what I originally did above. If this is a requirement for whatever you're developing, then certainly go ahead and do it this way, but I don't really think it's necessary.

Clickable/ Interactive contour plots in Matlab

I have formed a 2D matrix of 180X360. In fact, it is a LatXLong grid of 1°X1°. Each grid point has a value calculated according to my algorithm.
If I want to plot this LatXLong grid using any contour function, it is easy to do.
Now, what I need to do is to make this grid a clickable/ interactive contour plot in a way that when the user clicks anywhere on my grid plot, he gets an onscreen information or a further plot to be displayed specifically related to that grid point.
In short, I want to make a grid/contour plot in which all grid points are hyperlinks and linked to further background information.
check this answer:
if you don't want to have the variable as title of the plot, you can modify the code as:
function mouseExample()
h = plot(rand(10,1), 'o-');
set(h, 'ButtonDownFcn',#buttonDownCallback)
function out = buttonDownCallback(o,e)
p = get(gca,'CurrentPoint');
out = p(1,1:2);
% title( sprintf('(%g,%g)',p) ) % --> no need this line anymore
end
end
the information is saved in the P variable that you can use later.
To get started, look into ginput and text. ginput will let you click on points in your plot and return the coordinates to some function that can generate information to be displayed in the current plot using text of by opening another figure.
You can use ginput in a loop to display multiple data points as you go:
for t = 1:10
[x,y] = ginput(1);
text(x,y,'some info');
end
I don't know of a way to remove the gird lines. NKN's solution might do that for you.

Is there any way to restrict the plots in one grapgh?

I'm trying to plot several signals in one graph and i would like to restrict them and sort of minimize it so all my signals will be clear (more or less).
I have no idea how to do it. I'm adding an image so what i need to do will be clearer.
My data changes but in general it's the mean intensity of each column of a certain area in an intensity image.I tried to do it like with the same idea as you but i don't get the right plot as i wanted. A is the relevant matrix,b is the matrix with shifted values:
for i=1:20
b(i,:)=A(i,:)+(100*i);
plot(b(i,:))
hold on
end
I will also add 2 images: one is the plot of all the 20 signals that i get and the other one is the plot of only the first signal. I don't understand why do they look so different.
You can try something like that :
x = [1:100]; %Distance 1 to 100
y = F(x) % Your first function (signal)
y2 = 0.5*G(x) % Your second function (signal)
plot(x,y,x,y2); % plot both function in a single plot.
hleg1 = legend('Intensity t1,'Intensity t27');
So you have your signal at intensity t27 half cut for each value ( 0.5 ), so it shift down.

Getting pixel coordinates efficiently in Matlab

I would like to create a function in Matlab that, given an image, will allow one to select a pixel by clicking on it in the image and return the coordinates of the pixel. Ideally, one would be able to click on several pixels in the image in succession, and the function would store all the respective coordinates in a matrix. Is there a way to do this in Matlab?
ginput
Graphical input from mouse or cursor
Syntax
[x,y] = ginput(n)
[x,y] = ginput
[x,y,button] = ginput(...)
Description
[x,y] = ginput(n) enables you to
identify n points from the current
axes and returns their x- and
y-coordinates in the x and y column
vectors. Press the Return key to
terminate the input before entering n
points.
I think this is what you want:
A=imread('filename.jpg');
image(A)
[x,y]=ginput()