Home > data-utility > granger_causality > gcause_libs > visualize_time_series.m

visualize_time_series

PURPOSE ^

This is a plotting function for visualizing temperol pattens

SYNOPSIS ^

function visualize_time_series(data, args)

DESCRIPTION ^

 This is a plotting function for visualizing temperol pattens
 For input format, please see the function get_test_data() below
 
 Example:
 >>>  args.legend = {'Event1'; 'Event2'; 'Event3'; 'Event4'};
 >>>  plot_temp_patterns({}, 1, args)

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function visualize_time_series(data, args)
0002 % This is a plotting function for visualizing temperol pattens
0003 % For input format, please see the function get_test_data() below
0004 %
0005 % Example:
0006 % >>>  args.legend = {'Event1'; 'Event2'; 'Event3'; 'Event4'};
0007 % >>>  plot_temp_patterns({}, 1, args)
0008 
0009 % add other vs target
0010 
0011 % debugging:
0012 % visualize_cevent_patterns(data, args)
0013 
0014 LENGTH_CEVENT = 3;
0015 
0016 % if isfield(args, 'text_offset')
0017 %     text_offset = args.text_offset;
0018 % else
0019 %     text_offset = 20;
0020 % end
0021 
0022 figure_bgcolor = [1 1 1];
0023 text_bgcolor = figure_bgcolor;
0024 
0025 if isempty(data)
0026     error('Input data matrix is empty!');
0027 end
0028 
0029 if isfield(args, 'trial_times')
0030 %     max_trial_due = max(args.trial_times(:,2)-args.trial_times(:,1));
0031 %     text_offset = text_offset * (max_trial_due/100);
0032     text_offset = args.trial_times(1,1) - 0.1;
0033     
0034     % reverse visualization order
0035     if size(data, 1) > 2 % there are multiple trials
0036         data = flip(data);
0037         args.trial_times = flip(args.trial_times);
0038 %         args.row_text = flip(args.row_text);
0039         args.time_ref = flip(args.time_ref);
0040     end
0041 end
0042 
0043 if ~exist('args', 'var')
0044     args.info = 'No user input information here';
0045 end
0046 
0047 % How many instances on each figure
0048 if isfield(args, 'MAX_ROWS')
0049     MAX_ROWS = args.MAX_ROWS;
0050 else
0051     MAX_ROWS = 20;
0052 end
0053 
0054 if isfield(args, 'colormap')
0055     colormap = args.colormap;
0056 else
0057     colormap = get_colormap();
0058 end
0059 
0060 if isfield(args, 'is_closeplot')
0061     is_closeplot = args.is_closeplot;
0062 elseif isfield(args, 'save_name')
0063     is_closeplot = true;
0064 else
0065     is_closeplot = false;
0066 end
0067 
0068 % preprocess cell data, transfer it into a matrix
0069 if iscell(data)
0070     num_data_stream = size(data, 2);
0071     data_new = {};
0072     max_num_cvent_data_column = nan(1,num_data_stream);
0073     
0074     % go through each stream (each column in the cell data)
0075     for dsidx = 1:num_data_stream
0076         data_column = data(:,dsidx);
0077         
0078         data_column_length = cellfun(@(data_one) ...
0079             size(data_one, 1), ...
0080             data_column, ...
0081             'UniformOutput', false);
0082         data_column_length = vertcat(data_column_length{:});
0083         list_cevent_length = unique(data_column_length(:,1));
0084         max_data_column_length = max(list_cevent_length);
0085         
0086         % if data is a cell and needs to be processed
0087         if sum(~ismember(list_cevent_length, 1)) > 0
0088             data_column_new = nan(length(data_column), max_data_column_length*LENGTH_CEVENT);
0089             for didx = 1:length(data_column)
0090                 data_column_one = data_column{didx};
0091                 for doidx = 1:max_data_column_length
0092                     if doidx <= size(data_column_one,1)
0093                         data_column_new(didx,(doidx-1)*3+1:doidx*3) = ...
0094                             data_column_one(doidx,1:3);
0095                     end
0096                 end
0097             end
0098         else
0099             data_column_new = vertcat(data_column{:});
0100             max_data_column_length = list_cevent_length(1);
0101         end
0102         if max_data_column_length < 1;
0103             tmp_len = length(data_column_length);
0104             data_column_new = nan(tmp_len, 3);
0105         end
0106         data_new{dsidx} = data_column_new;
0107         max_num_cvent_data_column(dsidx) = max(max_data_column_length, 1);
0108     end
0109     data = horzcat(data_new{:});
0110     tmp_count = 0;
0111     for tmpi = 1:length(max_num_cvent_data_column)
0112         prev_tmp_count = tmp_count + 1;
0113         tmp_count = tmp_count + max_num_cvent_data_column(tmpi);
0114         stream_position_new(prev_tmp_count:tmp_count) = ...
0115             tmpi;
0116     end
0117     if ~isfield(args, 'stream_position')
0118         args.stream_position = stream_position_new;
0119     end
0120 end
0121 
0122 % end
0123 [rows, cols] = size(data);
0124 if ~iscell(data)
0125     cols = cols / LENGTH_CEVENT;
0126 end
0127 
0128 if ~isfield(args, 'stream_position')
0129     args.stream_position = ones(1,cols);
0130 end
0131 
0132 if isfield(args, 'legend')
0133     if ~isfield(args, 'legend_location')
0134         if ~exist('cont_args', 'var')
0135             args.legend_location = 'NorthEastOutside';
0136         else
0137             args.legend_location = 'NorthWestOutside';
0138         end
0139     end
0140 end
0141 
0142 if isfield(args, 'ForceZero')
0143     if isfield(args, 'ref_index')
0144         ref_index = args.ref_index;
0145     elseif isfield(args, 'ref_column')
0146         ref_column = args.ref_column;
0147     else
0148         ref_column = 2;
0149     end
0150     
0151     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0152     if ~iscell(data)
0153         if isfield(args, 'time_ref')
0154             time_ref = args.time_ref;
0155         elseif exist('ref_column', 'var')
0156             time_ref = data(:,ref_column);
0157         else
0158             time_ref = data(ref_index(1), ref_index(2));
0159             time_ref = repmat(time_ref, size(data,1), 1);
0160         end
0161         
0162         tmp_ref_nan = sum(isnan(time_ref));
0163         if tmp_ref_nan > 0
0164             error('Error! There is nan data in the reference time column!');
0165         end
0166         data_mat = data;
0167     else
0168         data_mat = cell2mat(data);
0169         if isfield(args, 'time_ref')
0170             time_ref = args.time_ref;
0171         elseif exist('ref_column', 'var')
0172             time_ref = data(:,ref_column);
0173         else
0174             time_ref = data(ref_index(1), ref_index(2));
0175             time_ref = repmat(time_ref, size(data,1), 1);
0176         end
0177         if sum(isnan(time_ref)) > 0
0178 %             time_idx_list = sort([1:3:size(data_mat,2) 2:3:size(data_mat,2)]);
0179             nan_count_data = sum(isnan(data_mat));
0180             [I J] = find(nan_count_data);
0181             ref_column = min(setdiff(1:size(data_mat,2), J));
0182             if isfield(args, 'ref_column')
0183                 warning(['The reference column for ForceZero time has NaN ' ...
0184                     'values and thus is changd to column ' int2str(ref_column) '.']);
0185             end
0186             time_ref = data_mat(:,ref_column);
0187         end
0188     end
0189     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0190     for j = cols:-1:1
0191         data_mat(:,j*LENGTH_CEVENT-1) = data_mat(:,j*LENGTH_CEVENT-1) - time_ref;
0192         data_mat(:,j*LENGTH_CEVENT-2) = data_mat(:,j*LENGTH_CEVENT-2) - time_ref;
0193     end
0194 else
0195     data_mat = data;
0196 end
0197 
0198 if isfield(args, 'color_code') && strcmp(args.color_code, 'cevent_value')    
0199     value_idx_list = 3:LENGTH_CEVENT:size(data_mat,2);
0200     max_cevent_value = max(max(data_mat(:,value_idx_list)));
0201 end
0202 
0203 % to calculate how many figure will be needed in total
0204 num_figures = floor(rows/MAX_ROWS)+ceil(mod(rows/MAX_ROWS, 1));
0205 
0206 for fidx = 1:num_figures
0207     if isfield(args, 'figure_visible') && ~args.figure_visible
0208         h = figure('Visible','Off');
0209     else
0210         h = figure;
0211     end
0212     %% The first half of the figure
0213     hold on;
0214     
0215     % to get how many rows/instances will be in this figure
0216     if fidx == num_figures
0217         if mod(rows, MAX_ROWS) == 0
0218             rows_one = MAX_ROWS;
0219         else
0220             rows_one = mod(rows, MAX_ROWS);
0221         end
0222     else
0223         rows_one = MAX_ROWS;
0224     end
0225     
0226     if isfield(args, 'position_row_width')
0227         position_row_width = args.position_row_width;
0228     else
0229         position_row_width = 80;
0230     end
0231     
0232     if isfield(args, 'set_position')
0233         set(h, 'Position', args.set_position, 'Color', figure_bgcolor);
0234     else
0235         fig_position = [20 10 1600 (100+position_row_width*rows_one)];
0236         set(h, 'Position', fig_position, 'Color', figure_bgcolor);
0237     end
0238     
0239     % to get the sub chunk of data for this figure
0240     if fidx == num_figures
0241         sub_data_mat = data_mat((fidx-1)*MAX_ROWS+1:end,:);
0242     else
0243         sub_data_mat = data_mat((fidx-1)*MAX_ROWS+1:(fidx)*MAX_ROWS,:);
0244     end
0245     
0246     start_time_idx = 1:LENGTH_CEVENT:size(sub_data_mat,2);
0247     end_time_idx = 2:LENGTH_CEVENT:size(sub_data_mat,2);
0248     
0249     if isfield(args, 'xlim_list')
0250         xlim_list = args.xlim_list;
0251         min_x = xlim_list(1);
0252         max_x = xlim_list(2);
0253     else
0254         min_x = nanmin(nanmin(sub_data_mat(:,start_time_idx))) - 0.1;
0255         max_x = nanmax(nanmax(sub_data_mat(:,end_time_idx))) + 0.1;
0256         xlim_list = [min_x max_x];
0257     end
0258     
0259     text_offset = min_x - (max_x-min_x)/100;
0260     length_of_streams = length(unique(args.stream_position));
0261     each_stream_space = 1/length_of_streams;
0262     
0263     % draw legend cubics
0264     if isfield(args, 'legend') && isfield(args, 'colormap')
0265         for lidx = 1:length(args.legend)
0266             x = [min_x, min_x, min_x, min_x];
0267             y = [0.1, 1, 1, 0.1];
0268             if iscell(args.colormap)
0269                 color = args.colormap{lidx};
0270             else
0271                 color = args.colormap(lidx, :);
0272             end
0273             fill(x, y, color);
0274         end
0275     end
0276 
0277     if isfield(args, 'row_text')
0278         row_text_pos_y = nan(MAX_ROWS, 1);
0279     end
0280     
0281     % Draw the background bars - white / grey
0282     for rowidx = 1:MAX_ROWS
0283         % Draw left to right in each row
0284         x = [min_x, max_x, max_x, min_x];
0285         y = [(rowidx-1)*(1+each_stream_space), (rowidx-1)*(1+each_stream_space), ...
0286             rowidx*(1+each_stream_space), rowidx*(1+each_stream_space)];
0287         color = [1 1 1];
0288         fill(x, y, color);
0289     end
0290     
0291     max_y = 0;
0292     % Draw actual instances row by row
0293     for rowidx = 1:rows_one
0294         % Draw left to right in each row
0295         pos_num_old = -1;
0296         for columnidx = 1:cols
0297             cevent_one = data_mat(rowidx+(fidx-1)*MAX_ROWS,(columnidx-1)*3+1:(columnidx-1)*3+3);
0298             pos_num_new = args.stream_position(columnidx);
0299             if isfield(args, 'var_text')
0300                 if iscell(args.var_text)
0301                     var_text_one =  args.var_text{pos_num_new};
0302                 elseif ischar(args.var_text)
0303                     var_text_one = sprintf('%s%d', args.var_text, pos_num_new);
0304                 end
0305             end
0306             
0307             if ~(isempty(cevent_one) || sum(isnan(cevent_one)) > 0)
0308                 start_time = cevent_one(1);
0309                 end_time = cevent_one(2);
0310 %                 if isfield(args, 'is_cont2cevent') && args.is_cont2cevent()
0311                 if cevent_one(3) > 100
0312 %                     cevent_one
0313                     cevent_one(3) = cevent_one(3) - args.cont_value_offset;
0314                     cont_colormap = get_colormap(args.cont_color_str{pos_num_new}, args.convert_max_int);
0315                     color = get_color(cevent_one(3), args.convert_max_int, cont_colormap);
0316                 else
0317                     if ~isfield(args, 'color_code') || strcmp(args.color_code, 'cevent_type')
0318                         color = get_color(columnidx, cols, colormap); %get_color(cevent_one(3));
0319                     elseif isfield(args, 'color_code') && strcmp(args.color_code, 'cevent_value')
0320                         color = get_color(cevent_one(3), max_cevent_value, colormap);
0321     %                     args.edge_color = get_color(mod(cevent_one(3), 10), max_cevent_value, colormap);
0322                     end
0323                 end
0324                 [~, y] = create_square(start_time, end_time, rowidx, columnidx, color, args);
0325                 text_color = [0 0 0];
0326             elseif (cevent_one(3) == 0)
0327                 text_color = [1 0 0];
0328                 [~, y] = create_square(0, 0, rowidx, columnidx, [1 1 1], args);
0329             else % if there is variable, but no data inside
0330                 text_color = [1 1 1] * 0.8;
0331                 [~, y] = create_square(0, 0, rowidx, columnidx, [1 1 1], args);
0332             end
0333             
0334             y_new = mean(y);
0335             if pos_num_old ~= pos_num_new && isfield(args, 'var_text')
0336                 text(text_offset, y_new, var_text_one, 'FontSize', 8, 'Color', text_color, ...
0337                     'BackgroundColor', text_bgcolor, 'Interpreter', 'none', 'HorizontalAlignment', 'right');
0338             end
0339             pos_num_old = pos_num_new;
0340         end
0341         if isfield(args, 'row_text')
0342             row_text_pos_y(rowidx) = y(1);
0343         end
0344         max_y = rowidx*(1+each_stream_space);
0345     end
0346     
0347     if isfield(args, 'ylim_list')
0348         ylim_list = args.ylim_list;
0349         max_y = ylim_list(2);
0350     else
0351         ylim_list = [0 max_y];
0352     end
0353     
0354     % draw verticle lines according to the user
0355     if isfield(args, 'vert_line')
0356         for vidx = 1:length(args.vert_line)
0357             x = [args.vert_line(vidx), args.vert_line(vidx), args.vert_line(vidx)+0.01, args.vert_line(vidx)+0.01];
0358             y = [0, max_y, max_y, 0];
0359             color = [1 0 0];
0360             fill(x, y, 'r', 'EdgeColor', color);
0361         end
0362     end
0363 
0364     % set transpenrency, so the overlaps between cevents can be shown
0365     if isfield(args, 'transparency')
0366         alpha(args.transparency);
0367     end
0368     
0369     if isfield(args, 'legend')
0370         new_legend = cell(size(args.legend));
0371         for i = 1:length(args.legend)
0372             new_legend{i} = plot_no_underline(args.legend{i});
0373         end
0374         
0375         legend(new_legend, 'Location', args.legend_location);
0376     end
0377     
0378     if isfield(args, 'row_text')
0379         for rowidx = 1:rows_one
0380             txrowidx = rowidx+(fidx-1)*MAX_ROWS;
0381             if isfield(args, 'row_text_type') && strcmp(args.row_text_type, 'time')
0382                 row_text_one = sprintf('%s: %.1f-%.1f', args.row_text{txrowidx}, args.trial_times(rowidx, 1), args.trial_times(rowidx, 2));
0383             elseif iscell(args.row_text)
0384                 row_text_one = args.row_text{txrowidx};
0385             else
0386                 row_text_one = args.row_text;
0387             end
0388             text(max_x+0.1, row_text_pos_y(rowidx), row_text_one, 'FontWeight', 'bold', 'Interpreter', 'none');%, 'FontSize', 12, 'BackgroundColor', [1 1 1]); -1*length(row_text_one)
0389         end
0390     end
0391     
0392     xlim(xlim_list);
0393     ylim(ylim_list);
0394     
0395     if isfield(args, 'title')
0396         title(plot_no_underline(args.title), 'FontWeight', 'bold'); %, 'FontSize', 12, 'BackgroundColor', [1 1 1]
0397     end
0398     
0399     if isfield(args, 'xlabel')
0400         xlabel(args.xlabel);
0401     end
0402     
0403     set(gca, 'ytick', []);
0404     hold off;
0405     %% all the plotting is done, start saving
0406     if isfield(args, 'save_name')
0407         save_name = args.save_name;
0408         
0409         if isfield(args, 'save_multiwork_exp_dir')
0410             save_name = fullfile(args.save_multiwork_exp_dir, save_name);
0411         end
0412         if ~isfield(args, 'save_format')
0413             save_format = 'png';
0414         else
0415             save_format = args.save_format;
0416         end
0417     
0418         set(h,'PaperPositionMode','auto');
0419 %         if isfield(args, 'figure_visible') && ~args.figure_visible
0420         if num_figures < 2
0421             saveas(h, [save_name '.' save_format]);
0422         else
0423             saveas(h, [save_name '_' int2str(fidx) '.' save_format]);
0424         end
0425         
0426         if isfield(args, 'pause_before_save') && args.pause_before_save
0427             pause
0428         end
0429 %         print(h, '-dpsc', [save_name '_' int2str(fidx) '.' save_format]);
0430         if is_closeplot
0431             close(h);
0432         end
0433     end
0434 end
0435 
0436 end
0437 
0438 % Get color according to rainbow color cue pallet
0439 function color = get_color(k, k_base, colormap)
0440     if ~isempty(colormap)
0441         if iscell(colormap)
0442             color = colormap{k};
0443         else
0444             color = colormap(k, :);
0445         end
0446     else
0447         color = hsv2rgb([k/k_base,1,0.85]);
0448     end
0449 end
0450 
0451 % Draw one rectangle
0452 % x1: start time
0453 % x2: end time
0454 % y1: y axe coordinate (center)
0455 % color: color of the shape
0456 % height: the height of each rectangle, default value is 0.25
0457 function [x, y] = create_square(x1, x2, y1, cidx, color, args)          
0458     length_of_streams = length(unique(args.stream_position));
0459     each_stream_space = 1/length_of_streams;
0460     position_value = args.stream_position(cidx);
0461 %         color = color*(each_stream_space*position_value)+...
0462 %             (1-each_stream_space*position_value);
0463     y1 = (y1-1)*(1+each_stream_space);
0464     y1 = y1 + (length_of_streams-position_value+1)*each_stream_space;    
0465     
0466     if ~isfield(args, 'height')
0467         height = each_stream_space*0.5; %0.2;
0468     else
0469         height = args.height;
0470     end
0471     if isfield(args, 'edge_color')
0472         edge_color = args.edge_color; %0.2;
0473     else
0474         edge_color = 'none';
0475     end
0476     
0477     x = [x1, x2, x2, x1];
0478     y = [y1-height, y1-height, y1+height, y1+height];
0479     rect = fill(x, y, color, 'EdgeColor', 'k');
0480 end

Generated on Wed 24-May-2017 00:00:56 by m2html © 2005