Plotting data on a map in matlab - matlab

I am using MATLAB R2015a. I have defined a grid which is basically a matrix that stores the latitudes of the grid points in the first column and the longitudes of the grid points in the second column I have some data for energy of an earthquake for a region stored in a column vector where each element corresponds to the energy at the corresponding grid point. I have done a surface plot using this code (here e_lat and e_long are the first and second columns of the grid matrix respectively):-
function [b] = cumulative_plot( beam, e_lat,e_long, t_start, t_end)
%CUMULATIVE_PLOT Plots the cumulative energy of the earthquake
%% Input Arguments
% *beam* - Energy for each time increment (columns) for each grid point (rows)
%
% *e_lat* - Vector containing Latitudes of the grid points
%
% *e_long* - Vector containing Longitudes of the grid points
%
% *t_start* - starting time
%
% *t_end* - ending time
%
% *t_start* and *t_end* define the time window within which the energy is
% to be considered
%% Code
b = [];
b = sum(beam(:,t_start:t_end)')'; % Adding the energy within the time window
b = b./max(b); % Normalising
fn = 'cumulative_energy.txt';
f = fopen(fn,'w');
for i=1:length(e_lat)
fprintf(f,'%f %f %f \n',e_long(i),e_lat(i),b(i));
end
fclose(f);
energy_surf = fit([e_long,e_lat],b, 'loess');
plot(energy_surf,'style','contour');
hold on;
plot3(73.6400 ,34.5239 ,20,'s','MarkerSize',20,'MarkerEdgeColor','k','MarkerFaceColor','k')
hold on;
plot3(94.709,23.03,20,'s','MarkerSize',20,'MarkerEdgeColor','b','MarkerFaceColor','b')
shading interp
alpha(1)
view(0,90)
box off
colorbar
title(['Cumu Energy(0.05 - 0.2 Hz) at seconds = ' num2str(t_start )],'FontWeight','bold','FontSize',15,'FontName','Times');
xlabel('Long/degree','FontWeight','bold','FontSize',13,'FontName','Times');
ylabel('Lat/degree','FontWeight','bold','FontSize',13,'FontName','Times');
end
This is an example (the actual data that I am processing):-
cumulative_plot(b_corr,e_lat,e_long,1,20);
I want to make a contour plot of this energy data on a geographic map of the region specified. Is this possible?
To give a better idea, this is what I have right now :-
And this is kind of what I want to achieve (without the purple circular markers and other things. Just the base energy) :-

If you have the bmp image of the mountain details, save the data in RGB format, and mix it with the data of the cumulative energy scale by its intensity. Intensity provide the alpha blending value.

Related

Plotting Eye Diagram from ADS Data in MATLAB

I have a data file (Sample_Eye_1.txt) which I obtained from the simulation plot of ADS Keysight. It has 3 fields - "Index", "Time" and "Voltage". Now the eye diagram plot will be voltage vs time. There can be different voltages at the same time at only different index. So index can be seen as a data filter field or similar like that. The plot in ADS simulation is the following
You can see that the line plot is plotted like it is superimposed on different lines.
Now when I plot data in MATLAB voltage vs time, it is not superimposed somehow. This is the plot generated plot of my matlab code which is just simple xy plot.
My MATLAB code:
% open data file
fid = fopen('Sample_Eye_1.txt');
% Read data in from csv file
readData = textscan(fid,'%f %f %f','Headerlines',1,'Delimiter',',');
% Extract data from readData
index_Data = readData{1,1}(:,1);
xData = readData{1,2}(:,1);
yData = readData{1,3}(:,1);
% Plot Data
f1 = figure(1);
cla; hold on; grid on;
%set(gca, 'XTick',[0 5 10 15 20 25 30]);
%set(gca,'XTick',0:0.1e-8:1e-8)
%set(gca,'XTickLabel',0:1:10)
plot(xData,yData,'r-');
title('Eye Diagram')
xlabel('Time(ns)')
ylabel('Density(V)')
Can anyone help me to generate the plot like the plot of ADS simulation plot?
Note: The data is big (around 2.7 Mb). If I truncate the data, the problem cannot be fully understood.
Your code is fine, the problem is due to the way you plot the data.
plot(xData,yData,'r-');
connects all the points with a line segment, this implies that the "holes" of the eye diagram are "closed" when the lines cross them.
You can obtain the expected plot, by simply change the "lines" with "dots"
plot(xData,yData,'r.')
If you want to have a plot more "similar" to the reference one, you can identify the input points with the same index an plot them (again, with "dots") in a loop in which, at each iteration you can change the colot of the dots.
In the following, you can find an updated versin of your code in which the loop is used to plot the data.
Edit to answer the comment
In general, you can specify the color of the marker by setting the color property either by specifying the "name" of the color or its RGB triplet (ref. to the "plot" function documentation for the details).
In your case, the "unique" indices are 16 whike the available "name" of the color are only 8 therefore you have to define the 16 color by defining explicitly the RGB triplet (which can be boring).
Notice, that the most of your data correspond to the first three indices, so, you could define three colors and let the other be random.
In the updated version of the code I've used this approach, defining the matrix dot_color as follows
dot_color=[0 0 .5
.5 .9 .9
0.9 .5 0
rand(length(uni_idx-3),3)]
this means, I've chosed the first three color and used random numbers for the others.
Of course, you can "manually define also the other colors (the value of each entry in the matrix should range between 0 and 1).
fid = fopen('Sample_Eye_1.txt');
% Read data in from csv file
readData = textscan(fid,'%f %f %f','Headerlines',1,'Delimiter',',');
fclose(fid)
% Extract data from readData
index_Data = readData{1,1}(:,1);
% Identify the unique indices
uni_idx=unique(index_Data);
xData = readData{1,2}(:,1);
yData = readData{1,3}(:,1);
% Plot Data
f1 = figure(1);
cla; hold on; grid on;
%set(gca, 'XTick',[0 5 10 15 20 25 30]);
%set(gca,'XTick',0:0.1e-8:1e-8)
%set(gca,'XTickLabel',0:1:10)
% plot(xData,yData,'r-');
% Loop over the indices to plot the corresponding data
% Define the color of the dots
dot_color=[0 0 .5
.5 .9 .9
0.9 .5 0
rand(length(uni_idx-3),3)]
for i=1:length(uni_idx)
idx=find(index_Data == uni_idx(i));
% plot(readData{1,2}(idx,1),readData{1,3}(idx,1),'.')
plot(readData{1,2}(idx,1),readData{1,3}(idx,1),'.','color',dot_color(i,:))
end
title('Eye Diagram')
xlabel('Time(ns)')
ylabel('Density(V)')

Setting axis limit for plot

I want to set the limit for X axis in this plot from 0 to 325. When i am using xlim to set the limits (commented in the code). It doesn't work properly. When i use xlim, the entire structure of plot changes. Any help will be appreciated.
figure
imagesc(transpose(all_area_for_visual));
colormap("jet")
colorbar('Ticks',0:3,'TickLabels',{'Home ','Field','Bad house','Good house'})
xlabel('Time (min)')
tickLocs = round(linspace(1,length(final_plot_mat_missing_part(2:end,1)),8));
timeVector = final_plot_mat_missing_part(2:end,1);
timeForTicks = (timeVector(tickLocs))./60;
xticks(tickLocs);
xticklabels(timeForTicks);
%xlim([0 325]);
ylabel('Car identity')
yticks(1:length(Ucolumnnames_fpm))
yticklabels([Ucolumnnames_fpm(1,:)])
If I get you right, you want to plot only part of the data in all_area_for_visual, given by a condition on tickLocs. So you should first condition the data, and then plot it:
% generate the vector of x values:
tickLocs = round(linspace(1,length(final_plot_mat_missing_part(2:end,1)),8));
% create an index vector (of logicals) that marks the columns to plot from the data matix:
validX = tickLocs(tickLocs<=325);
% plot only the relevant part of the data:
imagesc(transpose(all_area_for_visual(:,validX)));
% generate the correct ticks for the data that was plotted:
timeVector = final_plot_mat_missing_part(2:end,1);
timeForTicks = (timeVector(tickLocs(validX)))./60;
xticks(tickLocs(validX));
% here you continue with setting the labels, colormap and so on...
imagesc puts the data in little rectangles centered around integers 1:width and 1:height by default. You can specify what the x and y locations of each data point by adding two vectors to the call:
imagesc(x,y,transpose(all_area_for_visual));
where x and y are vectors with the locations along the x and y axes you want to place the data.
Note that xlim and xticks don’t change the location of the data, only the region of the axis shown, and the location of tick marks along the axis. With xticklabels you can change what is shown at each tick mark, so you can use that to “fake” the data locations, but the xlim setting still applies to the actual locations, not to the labels assigned to the ticks.
I think it is easier to plot the data in the right locations to start with. Here is an example:
% Fake your data, I'm making a small matrix here for illustration purposes
all_area_for_visual = min(floor(cumsum(rand(20,5)/2)),3);
times = linspace(0,500,20); % These are the locations along the time axis for each matrix element
car_id_names = [4,5,8,15,18]; % These are the labels to put along the y-axis
car_ids = 1:numel(car_id_names); % These are the locations to use along the y-axis
% Replicate your plot
figure
imagesc(times,car_ids,transpose(all_area_for_visual));
% ^^^ ^^^ NOTE! specifying locations
colormap("jet")
colorbar('Ticks',0:3,'TickLabels',{'Home ','Field','Bad house','Good house'})
xlabel('Time (min)')
ylabel('Car identity')
set(gca,'YTick',car_ids,'YTickLabel',car_id_names) % Combine YTICK and YTICKLABEL calls
% Now you can specify your limit, in actual time units (min)
xlim([0 325]);

In Matlab, how to draw lines from the curve to specific xaxis position?

I have a spectral data (1000 variables on xaxis, and peak intensities as y) and a list of peaks of interest at various specific x locations (a matrix called Peak) which I obtained from a function I made. Here, I would like to draw a line from the maximum value of each peaks to the xaxis - or, eventually, place a vertical arrow above each peaks but I read it is quite troublesome, so just a vertical line is welcome. However, using the following code, I get "Error using line Value must be a vector of numeric type". Any thoughts?
X = spectra;
[Peak,intensity]=PeakDetection(X);
nrow = length(Peak);
Peak2=Peak; % to put inside the real xaxis value
plot(xaxis,X);
hold on
for i = 1 : nbrow
Peak2(:,i) = round(xaxis(:,i)); % to get the real xaxis value and round it
xline = Peak2(:,i);
line('XData',xline,'YData',X,'Color','red','LineWidth',2);
end
hold off
Simple annotation:
Here is a simple way to annotate the peaks:
plot(x,y,x_peak,y_peak+0.1,'v','MarkerFaceColor','r');
where x and y is your data, and x_peak and y_peak is the coordinates of the peaks you want to annotate. The add of 0.1 is just for a better placing of the annotation and should be calibrated for your data.
For example (with some arbitrary data):
x = 1:1000;
y = sin(0.01*x).*cos(0.05*x);
[y_peak,x_peak] = PeakDetection(y); % this is just a sketch based on your code...
plot(x,y,x_peak,y_peak+0.1,'v','MarkerFaceColor','r');
the result:
Line annotation:
This is just a little bit more complicated because we need 4 values for each line. Again, assuming x_peak and y_peak as before:
plot(x,y);
hold on
ax = gca;
ymin = ax.YLim(1);
plot([x_peak;x_peak],[ymin*ones(1,numel(y_peak));y_peak],'r')
% you could write instead:
% line([x_peak;x_peak],[ymin*ones(1,numel(y_peak));y_peak],'Color','r')
% but I prefer the PLOT function.
hold off
and the result:
Arrow annotation:
If you really want those arrows, then you need to first convert the peak location to the normalized figure units. Here how to do that:
plot(x,y);
ylim([-1.5 1.5]) % only for a better look of the arrows
peaks = [x_peak.' y_peak.'];
ax = gca;
% This prat converts the axis unites to the figure normalized unites
% AX is a handle to the figure
% PEAKS is a n-by-2 matrix, where the first column is the x values and the
% second is the y values
pos = ax.Position;
% NORMPEAKS is a matrix in the same size of PEAKS, but with all the values
% converted to normalized units
normpx = pos(3)*((peaks(:,1)-ax.XLim(1))./range(ax.XLim))+ pos(1);
normpy = pos(4)*((peaks(:,2)-ax.YLim(1))./range(ax.YLim))+ pos(2);
normpeaks = [normpx normpy];
for k = 1:size(normpeaks,1)
annotation('arrow',[normpeaks(k,1) normpeaks(k,1)],...
[normpeaks(k,2)+0.1 normpeaks(k,2)],...
'Color','red','LineWidth',2)
end
and the result:

Change the LineWidth in some parts of a plot

I have an ECG signal and some special points of it calculated.
I want to have thicker LineWidth between those points (each pair). I did a sample with brush.
Here are my variables,
signal % the ECG signal
t % time
Q % location of red points
T % location of yellow points
Four of these pairs are visible in picture, but there are more.
Is it possible without loop _ hold on?
You can just use hold on and plot the data again on the region of interest:
% Some dummy data
x = 0:0.01:10;
y = sin(x);
plot(x,y)
% Data that we want emphasized
% You can also select a subset of your existing data
x_start = 2;
x_end = 4;
x_thick_line = x_start:0.01:x_end;
y_thick_line = sin(x_thick_line);
% Plot over the existing plot with thicker line
hold on
plot([x_start x_end],[y_thick_line(1) y_thick_line(end)],'ro',...
x_thick_line,y_thick_line,'Color','r','LineWidth',6')
This gives the following result in Octave, should be the same in MATLAB:
You should plot that function three times (assuming a..b shall be styled differently):
0..a - standard settings
a..b - use alternate color / line_width / ...
b..end

ploting 3d graph in matlab?

I am currently a begineer, and i am using matlab to do a data analysis. I have a a text file with data at the first row is formatted as follow:
time;wave height 1;wave height 2;.......
I have column until wave height 19 and rows total 4000 rows.
Data in the first column is time in second. From 2nd column onwards, it is wave height elevation which is in meter. At the moment I like to ask matlab to plot a 3d graph with time on the x axis, wave elevation on the y axis, and wave elevation that correspond to wave height number from 1 to 19, i.e. data in column 2 row 10 has a let say 8m which is correspond to wave height 1 and time at the column 1 row 10.
I have try the following:
clear;
filename='abc.daf';
path='C:\D';
a=dlmread([path '\' filename],' ', 2, 1);
[nrows,ncols]=size(a);
t=a(1:nrows,1);%define t from text file
for i=(1:20),
j=(2:21);
end
wi=a(:,j);
for k=(2:4000),
l=k;
end
r=a(l,:);
But everytime i use try to plot them, the for loop wi works fine, but for r=a(l,:);, the plot only either give me the last time data only but i want all data in the file to be plot.
Is there a way i can do that. I am sorry as it is a bit confusing but i will be very thankful if anyone can help me out.
Thank you!!!!!!!!!!
Once you load your data as you do in your code above your variable a should be a 4000-by-20 array. You could then create a 3-D plot in a couple of different ways. You could create a 3-D line plot using the function PLOT3, plotting one line for each column of wave elevation data:
t = a(:,1); %# Your time vector
for i = 2:20 %# Loop over remaining columns
plot3(t,(i-1).*ones(4000,1),a(:,i)); %# Plot one column
hold on; %# Continue plotting to the same axes
end
xlabel('Time'); %# Time on the x-axis
ylabel('Wave number'); %# Wave number (1-19) on y-axis
zlabel('Wave elevation'); %# Elevation on z-axis
Another way to plot your data in 3-D is to make a mesh or surface plot, using the functions MESH or SURF, respectively. Here's an example:
h = surf(a(:,1),1:19,a(:,2:20)'); %'# Plot a colored surface
set(h,'EdgeColor','none'); %# Turn off edge coloring (easier to see surface)
xlabel('Time'); %# Time on the x-axis
ylabel('Wave number'); %# Wave number (1-19) on y-axis
zlabel('Wave elevation'); %# Elevation on z-axis
I don't quite understand what your function does, for example, I do not see any plot command.
Here's how I'd try to make a 3D plot according to your specs:
%# Create some data - time from 0 to 2pi, ten sets of data with frequency 1 through 10.
%# You would just load A instead (I use uppercase just so I know that A is a 2D array,
%# rather than a vector)
x = linspace(0,2*pi,100)';%#' linspace makes equally spaced points
w = 1:10;
[xx,ww]=ndgrid(x,w); %# prepare data for easy calculation of matrix A
y = ww.*sin(xx.*ww);
A = [x,y]; %# A is [time,data]
%# find size of A
[nRows,nCols] = size(A);
%# create a figure, loop through the columns 2:end of A to plot
colors = hsv(10);
figure,
hold on,
for i=1:nCols-1,
%# plot time vs waveIdx vs wave height
plot3(A(:,1),i*ones(nRows,1),A(:,1+i),'Color',colors(i,:)),
end
%# set a reasonable 3D view
view(45,60)
%# for clarity, label axes
xlabel('time')
ylabel('wave index')
zlabel('wave height')
Or, you could try gnuplot. Fast, free and relatively easy to use. I use it to generate heat maps for datasets in the millions of rows.