Plot 2 sets of data on same plot in Matlab gui - matlab

I have created a matlab GUI that plot a graph.
I have a few issues;
I cannot change the date format using datetic.
I cannot eliminate scientific notation from plot.
I have a 2nd plot that I wan to add to add as a 2nd Y axis. The x axis are the same.
I my original live script I could plot on 2nd y axis using the yyaxis right and yyleft commands.
These do not work in GUI??
The current GUI
% Code that executes after component creation
function startupFcn(app)
load covid_data.mat
% Code to summ all cumlative data at Global Level and plot
[R,C]=size(covid_data);
for i=1:R-1
for j=1:C-3
% Read cumulative case count covid into array of specified row
CumCases(i,j) =covid_data{i+1,j+2}(1,1);
CumDeaths(i,j) =covid_data{i+1,j+2}(1,2);
end
end
SumAllCumCase=sum(CumCases);
SumAllDeaths=sum(CumDeaths);
% Create vector of dates for use in plot bar charts
%datenum converts string to numeric date
for i=1:C-3
Date(i) =datenum(covid_data{1,i+2});
end
x = Date;
dateFormat = 6;
datetick('x',dateFormat);
app.SumAllCase = SumAllCumCase
app.SumAllDeath = SumAllDeaths
app.Dates=x
plot(app.UIAxes,app.Dates,app.SumAllDeath)
% plot(app.UIAxes,app.Dates,app.SumAllCase)

Related

Matlab - plotting function with a for loop over a matrix

I have an assignment which sounds like:
"“Grades per assignment”: A plot with the assignments on the x-axis and the grades on the y-axis. The x-axis must show all assignments from 1 to M, and the y-axis must show all grade −3 to 12. The plot must contain:
Each of the given grades marked by a dot. You must add a small random number (between -0.1 and 0.1) to the x- and y-coordinates of each dot, to be able tell apart the different dots which otherwise would be on top of each other when more than one student has received the same grade in the same assignment.
The average grade of each of the assignments plotted as a line"
For now i have created this function:
function gradesPlot(grades)
figure(2);
n_assignments=size(grades,2);
hold on; % Retain current plot when adding new plots.
for i = 1:n_assignments % Loop through every assignment.
% Scatter plot of assignment vs grades for that assignment.
% One assignment on every iteration.
n_assignments2=([1:size(grades,2)]);
scatter(n_assignments2,grades(:,i)'jitter', 'on', 'jitterAmount', 0.1)
hold off; % Set the hold state to off.
end
%Titles to the plot
title('Grades per assignment');
xlabel('Assignment');
ylabel('Given grades');
break;
end
when i run the code it says that the vectors must be same length.
And it looks like it doesn't loop over the matrix more than ones.
The test grades i am using as input is looking like this:
grades=[[-3,4,10];[7,4,12];[7,10,12];[0,4,4];[2,2,2];[2,2,2]]
I hope some of you guys can help me get this function to work - maybe in an easier way?
Thank you in advance
You should not turn off hold since it is tells MatLab to plot everything in the current active plot, roughly speaking. You can find a possible solution to your problem down below: I added some explanations in comments.
function gradesPlot(grades)
figure(2);
% Extract the relevant information: number of assignements, number of grades
[n_assignments,n_grades] = size(grades);
hold on; % Retain current plot when adding new plots.
for i = 1:n_assignments % Loop through every assignment.
% Scatter plot of assignment vs grades for that assignment.
% One assignment on every iteration
% For Scatter, you have to provide 2 vectors of the same size: in this
% way, we are putting al the dots corresponding to the grades of the
% i-th assignement in correspondence of the i-th coordinate on the x
% axis. We are also temporary saving in h the handle to the attributes
% of the dots, in order to retrieve the color.
h = scatter(i*ones(n_grades,1),grades(i,:),'jitter', 'on', 'jitterAmount', 0.1);
% This plots the horizontal line corresponding to the average of the
% grades related to the i-th assignement
l = line([i-0.5 i+0.5],[1,1]*mean(grades(i,2:end)));
% For using the same color as the dots.
l.Color = h.CData;
end
%Titles to the plot
title('Grades per assignment');
xlabel('Assignment');
ylabel('Given grades');
axis([0 n_assignments+1 -4 13])
end
Remember that the break command must be used inside a loop, not for exiting a function. Use return if you desire.

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]);

Highlight specific section of graph in MATLAB

I wish to highlight/mark some parts of a array via plot in MATLAB. After some research (like here) I tried to hold the first plot, find the indexes for highlighting and then a new plot, only with those points. However, those points are being drawn but all shifted to the beginning of the axis:
I'm currently trying using this code:
load consumer; % the main array to plot (157628x10 double) - data on column 9
load errors; % a array containing the error indexes (1x5590 double)
x = 1:size(consumer,1)'; % returns a (157628x1 double)
idx = (ismember(x,errors)); % returns a (157628x1 logical)
fig = plot(consumer(:,9));
hold on, plot(consumer(idx,9),'r.');
hold off
Another thing I would like to do was highlighting the whole section of the graph, like a "patch" on the same sections. Any ideas?
The trouble is that you are only providing the y-axis data to the plot function. By default, this means all data is plotted on the 1:numel(y) x locations of your plot, where y is your y-axis data.
You have 2 options...
Also provide x-axis data. You've already got the array x anyway!
figure; hold on;
plot(x, consumer(:,9));
plot(x(idx), consumer(idx,9), 'r.');
Aside: I'm slightly confused why you create idx. If errors is as you describe it (indexes of the array) then you should just be able to use consumer(errors,9).
Make all data which you don't want to appear equal to NaN. Because of the way you're loading your error indices in, this is less quick and easy. Basically you'd copy consumer(:,9) into a new variable, and index all undesirable points to set them equal to NaN.
This method has the benefit of breaking up discontinuous sections too.
y = consumer(:,9); % copy your y data before changes
idx = ~ismember(x, errors); % get the indices you *don't* want to re-plot
y(idx) = NaN; % Set equal to NaN so they aren't plotted
figure; hold on;
plot(x, consumer(:,9));
plot(x, y, 'r'); % Plot all points, NaNs wont show

Plotting data on a map in 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.

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.