I need assistance making a nice contour plot. I have data from an underwater glider that dives and climbs repeatedly from the surface of the ocean to around 30 m, in this case.
I think my issue is with interpolating the data, and I am not sure how to proceed. Here is the contour plot of density I have generated this far.
The Contour plot of density was generated using this code
xlin = linspace(min(time),max(time),500);
ylin = linspace(min(depth),max(depth),500);
[X,Y] = meshgrid(xlin,ylin);
Z = griddata(time,depth,density,X,Y);
[C,h] = contour(X,Y,Z,[1022.0, 1022.5, 1023.0, 1023.5, 1024.0, 1024.5, 1025.0, 1025.5, 1026.0],'color',[0.5 0.5 0.5]);
v = [1022.0, 1022.5, 1023.0, 1023.5, 1024.0, 1024.5, 1025.0, 1025.5, 1026.0];
clabel(C,h,v,'fontsize',8);
set(gca,'ydir','reverse');
I want the plot to have smooth contour lines. Once I get the contour plot to look good I will overlay it on salinity and temperature scatter plots.
Please let me know how I can make a better looking contour plot.
Is it an issue with interpolation? Or the way I gridded the data?
Thanks very much! Please be specific and give code examples if you've played with the data.
Here is the time, depth, and density matlab data: https://www.dropbox.com/s/agi70zh7haggf07/data.mat?dl=0
The problem is that bunch of your interpolated data are missing. I mean that Z has a bunch of NaNs:
xlin = linspace(min(time),max(time),500);
ylin = linspace(min(depth),max(depth),500);
[X,Y] = meshgrid(xlin,ylin);
Z = griddata(time,depth,density,X,Y);
%surf(X,Y,Z) %also interesting
spy(isnan(Z));
Result:
Your input data are somehow ill-defined, and griddata gives up. Here's why:
>> sum(isnan(density))
ans =
3174
Fix the NaNs in your raw data, and you'll most probably fix the plot.
Update
I threw away your NaNs:
inds=~isnan(density);
time=time(inds);
depth=depth(inds);
density=density(inds);
to see how the result looks like. It turns out that your original code is already looking OK to me!
Original on the left, de-NaNed version on the right:
So... maybe your datetime transformation is off? Or your time limits, not showed in your original code?
Related
I would like to be able to overlay isolines over a filled contour or surface as it is done in this figure:
Can matlab overlay contour and contourf plots?
So far, I have tried this:
[X,Y] = meshgrid(x_cases,y_cases);
Points = length(x_cases)*length(y_cases);
resX = reshape(X,Points,1);
resY = reshape(Y,Points,1);
resZ = reshape(DataGrid_a,Points,1);
scatter(resX,resY,[],resZ,’filled’)
hold on
contour(X,Y,DataGrid_b,'ShowText','on')
But I have to reduce the transparency of my scatter plot to be able to see the contour lines from DataGrid_b, it would be more ideal to not change the transparency and overlay my isolines. I appreciate any input you may give me!
Thanks!
The simplest solution (and it's very hack) is to take advantage of the fact that 2D plots are plotted at Z = 0; So put your scatter points at some Z value below that.
scatter3(resX,resY,-ones(size(resX)),[],resZ,’filled’)
view(2)
hold on
contour(X,Y,DataGrid_b,'ShowText','on')
I am a bit struggling with my polar plot. I am playing with strikes and dips, and for each pair of those, an "intensity". I'd like to plot this surface/contourf/whatever function on my polarplot. I cannot find the handle to do so. Dpp2 contains the intensity value for a given theta and rho/ strike and dip.
xTmp = (0:4:360);
yTmp = (0:22.5:90);
[strike,dip]= meshgrid(deg2rad(xTmp),deg2rad(yTmp));
dip2 = rad2deg(dip);
strike2 =rad2deg(strike);
figure('name', 'COLD');
polarplot([0 360],[0 90]);
s = surf(strike2, dip2, DPp2);
polarplot(s);
colormap
I've tried something like that, which obviously doesn't work.
cheers,
Flo
As far as I know there is no way of creating a surface plot directly in a polarplot.
One workaround is to manually create your polar axis plot. You can find an example here.
Another workaround would be to use
polarscatter to create a scatter plot (which looks simmilar in case you have a tight grid) Have a look at this.
Because you mentioned the handle: In case you want a handle to the axes have a look at polaraxes from here.
The polar scatter wasn't working, so I tried another function, which seems to work according to this page: https://fr.mathworks.com/matlabcentral/answers/95796-how-do-i-create-a-contour-plot-in-polar-coordinates
I am note quite there yet, the contour map isn't "wrapped" around my polar plot, but so far it's compiling. If anyone has an idea on how to superimpose the contour map onto the polar plot ?
dip2 = rad2deg(dip);
strike2 =rad2deg(strike);
h = polar([0 360],[0 90]);
hold on;
contourf(strike2,dip2,DPp2);
% Hide the POLAR function data and leave annotations
set(h,'Visible','off')
% Turn off axes and set square aspect ratio
axis off
axis image
I am in need of plotting a 2D spectrogram of a signal in Matlab. I need it for a printed assignment, hence the 3D image makes no sense. However, when the signal is plotted using Spectrogram it automatically produces a 3D plot of the signal.
My Code:
Dataset = 1; % Dataset to be analysed
N = 1024; % Window size
Beta = 12; % Kaiser window beta value (small = narrow main lope)
Overlap = 800; % Window overlap
Threshold = -150; % Minimum magnitude before threshold
spectrogram(Enclosure{Dataset}(1:end),kaiser(N,Beta),Overlap,2048,fs,'MinThreshold',Threshold,'yaxis');
which produces a graph that looks like this:
But it is seen from the top, and the graph is really showing this:
The reason why i need it to specifically be 2D (and why i don't settle with a screenshot) is because i am using Matlab2tikz to convert Matlab figures into Tikz figures in LaTex. with the 3D images i get figures of +100 Mb and 2D will reduce the size to <1Mb.
I don't know what version of Matlab you are using but in 2015a you should be able to get a handle to the figure with the 3D plot and change the view angle to 2D:
view(0,90);
I've also got an example of how you can make your own 2D plot from the outputs of spectrogram() using a similar method:
x = [0:0.01:100];
y = sin(5*x);
y = awgn(y,0.1);
[S,F,T,P] = spectrogram(y,200,0,length(y)*5,100);
[m,n] = size(P);
figure(2)
surf(F,T,zeros(n,m),P','EdgeColor','none')
view(0,90)
xlabel('Frequency')
ylabel('Time (s)')
The output looks like this:
Hopefully since there is no altitude information, the figure size might be smaller but I can't test that since I don't have Matlab2tikz.
One option is to capture whatever its plotted and then plot it as an image. You can do this using getframe
if you do
F=getframe(gca);
cla;
imshow(F.cdata);
You'll get exactly what you will be seeing before, but as an image.
However I think it defeats a bit the purpose of Matlab2Tikz, as the idea os that you have Tikz code describing your data...
You can try the following:
[~,F,T,ps]=spectrogram(Enclosure{Dataset}(1:end),kaiser(N,Beta),Overlap,2048,fs,'MinThreshold',Threshold,'yaxis').
% Output the spectrum in ps
imagesc(T,F,10*log10(ps))
% Generate a 2d image
view(270,90)
xlabel('Time [s]')
ylabel('Frequency [Hz]')
c=colorbar;
c.Label.String='Power [dB]';
% Extra setting to make the plot look like the spectrogram
Good luck
This question already has answers here:
Produce a 3D stem plot with a custom colormap in MATLAB
(2 answers)
Closed 7 years ago.
I have produced the following figure using MATLAB plot3 function.
This figure is not good.
Because, I think, it's too hard for readers to estimate the coordinates from this figure.
Points height (Z value) is too hard to be estimated from the figure.
What is missing in my figure that makes it hard to be interpreted ?
To Play with the data:
The visualized data is here. The function to produce my current figure is here. Either comment the mArrow3 call, or download it from here.
To better see height you can use stem3 to draw a vertical line from the floor to each point. You can enhance the representation with a semi-transparent patch at zero height to highlight the floor.
% // Random data
x = -20+50*rand(1,50);
y = 150*rand(1,50);
z = -5+10*rand(1,50);
%// With plot
figure
plot3(x,y,z,'.','markersize',8)
grid on
axis equal
view(-33, 14)
%// With stem3 and patch
figure
stem3(x,y,z,'.','markersize',8)
grid on
hold on
patch([-20 30 30 -20], [0 0 150 150], [0 0 0 0], 'k', ...
'edgecolor', [.5 .5 .5], 'FaceAlpha' , .1)
axis equal
view(-33, 14)
I think the problem might be intrinsic to these kind of plots: the 0d dots of your data are hard to interpret perspectivically, your brain can't decypher at which depth the data points are located. For instance, it would seem to me that you have no data poinst above z=0 and above x=15, which is obviously wrong, but my brain attributes most of your points to the z=-5 plane.
Unless your data points have finite volume which proportionally changes with distance (which can not be done with matlab, and probably wouldn't help much anyway), you might want to reconsider your way of visualization. How about having 3 plots, one each with camera along the x, y, and z axes?
EDIT: the suggestion of Luis Mendo makes me think I should probably have a more open mind when trying to answer a question:)
You could also use different colors/markers/point size to discriminate between various regions in your data. For instance values having z below 0 are red and those above are green. Here is a simple example using scatter3 with 4 distinct regions. Thanks to Luis Mendo for the dummy data.
clc;clear;close all
% // Random data...thanks Luis Mendo
x = -20+50*rand(1,50);
y = 150*rand(1,50);
z = -5+10*rand(1,50);
%// Get indices for various regions in your data
region1 = find(z>=-4 & z<-2);
region2 = find(z>=-2 & z<0);
region3 = find(z>=0 & z<2);
region4 = find(z>=2 & z<4);
%// Draw each region with its own color/size
scatter3(x(region1),y(region1),z(region1),20,'r','filled')
hold on
scatter3(x(region2),y(region2),z(region2),40,'y','*')
scatter3(x(region3),y(region3),z(region3),60,'g','filled')
scatter3(x(region4),y(region4),z(region4),80,'b')
grid on
view(-33, 14)
kkuilla's answer about heat map produced a much better result:
I was wondering how I can view point values off a contour plot.
I wish to obtain all the x-positions at the initial time, t=0 from my contour plot. Can this be done?
I have read on this forum about Choosing isolines from Matlab contour function however I wish to get the actual points.
Any suggestions is much appreciated.
Untested, but recall it to be something like this:
h = findobj(gcf,'Type','Line');
x = get(h,'XData');
y = get(h,'YData');