I have created a fitted surface from x, y, z data points. How do I insert data tips for the min and max value in the chart?
defDM_fit = fit([def_X, def_Y],def_Z,'cubicinterp');
clf;
figure(2)
plot(defDM_fit,[def_X, def_Y],def_Z);
using the following test code is raising an error "Invalid argument. The object has been deleted or does not support data tips":
datatip(defDM_fit, def_X(1), def_Y(1), def_Z(1))
And I do not know how to manage that tips show up at min and max value in the chart by code.
Plotting a fitted surface created with fit outputs a 2x1 graphics array. The first element is the surface (Surface object), the second element is a Line object that holds the points on which your data was fitted. In order to add datatips, you will have to use one of these two objects, and more probably the Surface object, for example:
load franke
T = table(x,y,z);
f = fit([T.x, T.y],T.z,'linearinterp');
p = plot( f, [T.x, T.y], T.z );
datatip(p(1),T.x(1),T.y(1),T.z(1))
The first argument of datatip is a graphic object, not a surface/line fit object.
defDM_fit = fit([def_X, def_Y],def_Z,'cubicinterp');
figure(2)
p=plot(defDM_fit,[def_X, def_Y],def_Z);
datatip(p, def_X(1), def_Y(1), def_Z(1))
There are many other things that may be wrong with your approach, particularly because you are showing a surface plot (surf) in your example, yet your code uses a line plot (plot). I am not even sure what the arguments even are, the way you are putting them.
Consider reading the documentation of the functions you are using, as they come with examples on how to use them: https://uk.mathworks.com/help/curvefit/fit.html
Related
I have a 2D numeric array (100x100 double) which looks like this when plotted on a surf plot:
I am trying to link the plot with the variable, and then delete some data points (say, one of the two peaks) both in the variable (make the selected points 0) and in the plot, by using the brush tool on the plot.
The problem is, when the variable and the plot are linked, the brushing tool selects the full rows for the points that fall on the selected area, as shown here:
Selection when data is linked (I want to avoid this type of selection):
Same selection, data not linked (this is what I want, but with linked data):
Is there any way to avoid this, and select only the points that I want?
Details about this phenomenon can be found here:
https://uk.mathworks.com/help/matlab/ref/matlab.graphics.interaction.internal.brush.html#mw_b080675e-afd3-4251-99d8-a8273e85dc6c
I have also tried using other types of plots (mesh, sky, etc), but I could not find any solutions.
As a minimal reproducible example, you can use the following code:
PeaksVariable = peaks;
surf(PeaksVariable)
linkdata on
brush on
You can get the brushed data points with
PeaksVariable = peaks;
brush on;
s = surf( PeaksVariable );
b = logical( s.BrushData );
Then set the brushed points to whatever value you want
PeaksVariable( b ) = NaN;
And optionally update the surface with the updated data variable
s.ZData = PeaksVariable;
I want to graph different ellipses at different heights (z-coordinates).
My idea was to write the following code:
z=0:1/64:3/8;
t=linspace(-pi,pi,25);
[t,z]=meshgrid(t,z);
x=cos(-t);
y=cos(-t-4*pi*z);
I would like MATLAB to read my code like:
"Find x and y, and plot at the corresponding height (z). By doing so, join the points such that you'll form an ellipse at constant z".
I'm not sure what kind of function I could use here to do this and was hoping for someone to tell me if there exists such a function that will do the job or something similar.
In case you're wondering, I want to graph the polarization of light given two counterpropagating beams.
EDIT: While this is similar to the question draw ellipse and ellipsoid in MATLAB, that question doesn't address plotting 2D ellipses in 3D axes, which is what I am trying to do.
This can be solved by removing the meshgrid, and just using a plain old for-loop.
t = linspace(-pi,pi,25);
z = 0:1/64:3/8
f = figure;
hold on;
for i = 1:length(z)
x=cos(-t); y=cos(-t-4*pi*z(i));
plot3(x,y,z(i)*ones(length(z),1));
end
The problem in the original code is that you're trying build the ellipses all at once, but each ellipse only depends on a single z value, not the entire array of z values.
When I run this code, it produces the following plot:
I am trying to plot some data with Matlab R2015a and as the data sets are changing for different plots I want to create the legend (semi-)automatically. I do this with a list of strings (called list) and then
leg = legend(list);
legtxt=findobj(leg,'type','text');
set(legtxt(1),'color','r');
set(legtxt(2),'color','b');
a.s.o. according to the entries.
However, no matter what index I give in the 'set(legtxt(i))' part, Matlab always tells me 'Index exceeds matrix dimensions.' Same, if I create the the legend manually by not using 'legend(list)' but explicitly typing the legend entries. Does anyone know why this happens or how to solve it? Thanks!
You need to use additional outputs from the call to legend. Specifically, check out the 2nd output called icons in the docs.
As for the error, the call to findobj(...) yields an empty vector, so matrix dimensions are indeed exceeded. Indeed (from the docs):
Starting in R2014b, the legend function returns a legend object. In
previous releases it returns an axes object.
So maybe that's why you can't use findobj to fetch legend text...
Anyhow here is how to solve your problem. In this example I create 3 plots and change the color of the text of the 1st and 2nd entry inside the legend:
x = 1:10;
y1 = sin(x);
y2 = cos(x);
y3 = x;
plot(x,y1,'y*',x,y2,'g--',x,y3,'k')
list = {'y1';'y2';'y3'};
%// You want to play with icons and possibly plots.
[leg,icons,plots,str] = legend(list)
set(icons(1),'color','r','FontSize',12)
set(icons(2),'color','b','FontSize',12)
Output:
Of course you can use the plots output to change any property you want of the plots to make them fit with their legend entry.
I have some sparse data and want to plot them as markers connected by a smooth, interpolated line - like the default behaviour of Microsoft Excel.
There are solutions to this problem easily found on the internet, but I find them unsatisfactory. What they do is: plot the sparse data as one data set drawing it as markers without lines, interpolate it with a method of choice and plot the interpolation as the second data set, with lines without markers.
The problem with these tricks is that in the legend the two data sets will be listed separately. I would expect a single data set depicted in the legend as a line crossing through a marker.
Is it possible in Matlab?
If you want to plot an interpolated line there are lots of ways to do that. You can try generating an interpolated line using the matlab interp1() function.
Let's create x and y data with no NaN.
x = randn(1,10)
y = randn(1,10)
If you want 1000 data points where previously you only had a few, that's pretty easy:
x2 = min(x):(max(x)-min(x))/1000:max(x)
y2 = interp1(x,y,x2,'cubic')
and you can plot your data and spline using
plot(x,y,'r+')
hold on
plot(x2,y2,'r-')
A custom legend is straightforward when you use handle graphics. You can plot a dummy data set with a red line passing through a marker using
h(1) = plot(NaN,NaN,'r-+')
lstring{1} = 'Data';
You can then add a legend that points to this data set using
legend(h,lstring)
You'll end up with something that looks roughly like this:
The nice thing about using handle graphics (i.e. the h) is you can throw whatever data series you want into the legend as h(end+1) and lstring{end+1}.
I'm currently producing a contour plot using
contour(x,y,z)
However, I would like to specify some additional contour lines to the ones provided.
I understand that I can use contour(x,y,z,v) where v is some vector containing values of the contour levels I would like but I don't really want to use this since I don't know exactly the levels.
Instead is it possible to plot the contour that goes through a specific point (x,y)?
Thanks.
You can overplot a second contour with a single, specific value for the contour, optionally specifying parameters like line width to make it obvious:
contour(x,y,z)
hold on
lev = z(n,m); % find the value you want in z
contour(x,y,z,lev,'Linewidth',2);