Home > Back-end >  Plotting X and Y variable based on grouping data by variable in separate columns
Plotting X and Y variable based on grouping data by variable in separate columns

Time:07-13

I'm fairly new to the Matlab community and need help with a particular plotting task! Any assistance would be greatly appreciated.

I've been tasked with creating an automated process that produces numerous 2d line graphs, using X (Elevation) and Y (Chainage) data based on survey data we have gathered in the field. This XY data needs to be split into differing figures in accordance to a variable within a 'Profile_ID' column. An example of the data is shown below:

Easting Northing Elevation Chainage FC Name Profile_ID
219578.603 101400.293 6.675 133.393 CE N/A 7b01346
219577.925 101400.621 6.088 134.146 X N/A 7b01346
219577.833 101400.709 6.037 134.267 X N/A 7b01346
219577.378 101400.789 5.904 134.714 X N/A 7b01346
219577.319 101400.987 5.887 134.850 X N/A 7b01346

The PROFILE_ID changes throughout the .txt file. The file is ordered based on profile_id and then chainage

However, I also need to overlay previous survey data to the same corresponding 'Profile_ID' graph. So, essentially I have 2 data sets which have an identical column layout, just with differing X and Y data. One is from a previous survey and one from the newest survey. I was hoping to find a way that allows me to run a for loop to create a figure for every iteration of 'profile_id' and then also overlay the previous surveys data, which has the same 'profile_id'.

I hope that this all makes sense, i've linked an example here: Example of desired graph produced by the script, for one iteration of 'Profile_ID'

Cheers!

clc
clear
close all

%Import inputs

point_file_old = readtable('7b7B3-2_20170627tp.csv'); %Input older file name here
matrix_profile_old = table2array(point_file_old(:,3:4)); %Extracting elevation & chainage column
id_old = point_file_old(:,7);
L_old = length(matrix_profile_old(:,1));

point_file_new = readtable('20220430_7b7B3-2tp.csv'); %Input newer file name here
matrix_profile_new = table2array(point_file_new(:,3:4)); %Extracting elevation & chainage column
id_new = point_file_new(:,7);
L_new = length(matrix_profile_new(:,1));
%Settings

chainage_old = matrix_profile_old(:,2); %Identifying old chainage column 
elevation_old = matrix_profile_old(:,1); %Identifying old elevation column 
chain_old_num = length(chainage_old); %Amount of rows in chainage 
elev_old_num = length(elevation_old) %Amount of rows in elevation  

chainage_new = matrix_profile_new(:,2); %Identifying old chainage column 
elevation_new = matrix_profile_new(:,1); %Identifying old elevation column 
chain_new_num = length(chainage_new); %Amount of rows in chainage 
elev_new_num = length(elevation_new); %Amount of rows in elevation 

t_old = table(chainage_old(:,1), elevation_old(:,1), table2array(id_old(:,1)));
t_new = table(chainage_new(:,1), elevation_new(:,1), table2array(id_new(:,1)));

G = findgroups(t_new(:,3));
temp = splitapply(@(varargin) {sortrows(table(varargin{:}),3)}, t_new, G); %order separated groups in terms of chainage

So I currently have the data sorted into groups and now need to plot each individual group and then finally overlay the previous data to corresponding group data.

CodePudding user response:

One approach is to combine all of the data (old and new) into a single table, then find the unique IDs and loop over them. For each ID you can identify the relevant rows and plot them.

Note that the table2array usage in your current code makes your life harder, tables are nice because you can index columns using the column names directly, so this:

table2array(point_file_new(:,3));

becomes this:

point_file_new.Elevation;

Commented code below:

data_old = readtable('7b7B3-2_20170627tp.csv'); %Input older file name here
data_old.Source(:) = {'Old'}; % Add this column so we can track the source later
data_new = readtable('20220430_7b7B3-2tp.csv'); %Input newer file name here
data_new.Source(:) = {'New'}; % Add this column so we can track the source later

data_all = [data_old; data_new]; % combine data into single table

IDs = unique( data_all.Profile_ID ); % Get unique Profile_ID values
NID = numel(IDs);                    % Number of unique IDs
for ii = 1:NID
    ID = IDs{ii};  % Current ID
    idxID = ismember( data_all.Profile_ID, ID ); % Rows with this ID
    idxOld = strcmp(data_all.Source, 'Old');     % Rows from old data
    idxOld = idxOld & idxID; % Rows from old data and this ID
    idxNew = strcmp(data_all.Source, 'New');     % Rows from new data
    idxNew = idxNew & idxID; % Rows from new data and this ID
    
    figure(); % Make a new figure for this ID
    hold on;  % hold so we can plot multiple lines
    plot( data_all.Elevation(idxOld), data_all.Chainage(idxOld), 'displayname', 'Old data' ); % plot old
    plot( data_all.Elevation(idxNew), data_all.Chainage(idxNew), 'displayname', 'New data' ); % plot new
    % Add labels/title
    xlabel( 'Chainage (m)' );
    ylabel( 'Elevation (m)' );
    title( ID );
    grid on;
    hold off; % done plotting
    legend('show','location','best');
end
  • Related