source: trunk/src/plot_field.m @ 748

Last change on this file since 748 was 748, checked in by sommeria, 10 years ago

update for 3D plots, panel Coordiantes introduces, while coordiantes now called Axes

File size: 58.9 KB
Line 
1%'plot_field': plot any field with the structure defined in the uvmat package
2%------------------------------------------------------------------------
3%
4%  This function is used by uvmat to plot fields. It automatically chooses the representation
5% appropriate to the input field structure:
6%     2D vector fields are represented by arrows, 2D scalar fields by grey scale images or contour plots, 1D fields are represented by usual plot with (abscissa, ordinate).
7%  The input field structure is first tested by check_field_structure.m,
8%  then split into blocks of related variables  by find_field_cells.m.
9%  The dimensionality of each block is obtained  by this function
10%  considering the presence of variables with the attribute .Role='coord_x'
11%  and/or coord_y and/or coord_z (case of unstructured coordinates), or
12%  dimension variables (case of matrices).
13%
14% function [PlotType,PlotParamOut,haxes]= plot_field(Data,haxes,PlotParam,PosColorbar)
15%
16% OUPUT:
17% PlotType: type of plot: 'text','line'(curve plot),'plane':2D view,'volume'
18% PlotParamOut: structure, representing the updated  plotting parameters, in case of automatic scaling
19% haxes: handle of the plotting axis, when a new figure is created.
20%
21%INPUT
22%    Data:   structure describing the field to plot
23%         (optional) .ListGlobalAttribute: cell listing the names of the global attributes
24%                    .Att_1,Att_2... : values of the global attributes
25%         (requested)  .ListVarName: list of variable names to select (cell array of  char strings {'VarName1', 'VarName2',...} )
26%         (requested)  .VarDimName: list of dimension names for each element of .ListVarName (cell array of string cells)
27%                      .VarAttribute: cell of attributes for each element of .ListVarName (cell array of structures of the form VarAtt.key=value)
28%         (requested) .Var1, .Var2....: variables (Matlab arrays) with names listed in .ListVarName
29
30%            Variable attribute .Role :
31%    The only variable attribute used for plotting purpose is .Role which can take
32%    the values
33%       Role = 'scalar':  (default) represents a scalar field
34%            = 'coord_x', 'coord_y',  'coord_z': represents a separate set of
35%                        unstructured coordinate x, y  or z
36%            = 'vector': represents a vector field whose number of components
37%                is given by the last dimension (called 'nb_dim')
38%            = 'vector_x', 'vector_y', 'vector_z'  :represents the x, y or z  component of a vector 
39%            = 'warnflag' : provides a warning flag about the quality of data in a 'Field', default=0, no warning
40%            = 'errorflag': provides an error flag marking false data,
41%                   default=0, no error. Different non zero values can represent different criteria of elimination.
42%
43%   haxes: handle of the plotting axes to update with the new plot. If this input is absent or not a valid axes handle, a new figure is created.
44%
45%   PlotParam: structure containing the parameters for plotting, as read on the uvmat or view_field GUI (by function 'read_GUI.m').
46%      Contains three substructures:
47%     .Axes: coordinate parameters:
48%           .CheckFixLimits:=0 (default) adjust axes limit to the X,Y data, =1: preserves the previous axes limits
49%     .Axes.CheckFixAspectRatio: =0 (default):automatic adjustment of the graph, keep 1 to 1 aspect ratio for x and y scales.
50%     .Axes.AspectRatio: imposed aspect ratio y/x of axis unit plots
51%            --scalars--
52%    .Scalar.MaxA: upper bound (saturation color) for the scalar representation, max(field) by default
53%    .Scalar.MinA: lower bound (saturation) for the scalar representation, min(field) by default
54%    .Scalar.CheckFixScal: =0 (default) lower and upper bounds of the scalar representation set to the min and max of the field
55%               =1 lower and upper bound imposed by .AMax and .MinA
56%    .Scalar.CheckBW= 1: black and white representation imposed, =0 color imposed (color scale or rgb),
57%                   =[]: automatic (B/W for integer positive scalars, color  else)
58%    .Scalar.CheckContours= 1: represent scalars by contour plots (Matlab function 'contour'); =0 by default
59%    .IncrA : contour interval
60%            -- vectors--
61%    .Vectors.VecScale: scale for the vector representation
62%    .Vectors.CheckFixVec: =0 (default) automatic length for vector representation, =1: length set by .VecScale
63%    .Vectors.CheckHideFalse= 0 (default) false vectors represented in magenta, =1: false vectors not represented;
64%    .Vectors.CheckHideWarning= 0 (default) vectors marked by warnflag~=0 marked in black, 1: no warning representation;
65%    .Vectors.CheckDecimate4 = 0 (default) all vectors reprtesented, =1: half of  the vectors represented along each coordinate
66%         -- vector color--
67%    .Vectors.ColorCode= 'black','white': imposed color  (default ='blue')
68%                        'rgb', : three colors red, blue, green depending
69%                        on thresholds .colcode1 and .colcode2 on the input  scalar value (C)
70%                        'brg': like rgb but reversed color order (blue, green, red)
71%                        '64 colors': continuous color from blue to red (multijet)
72%    .Vectors.colcode1 : first threshold for rgb, first value for'continuous'
73%    .Vectors.colcode2 : second threshold for rgb, last value (saturation) for 'continuous'
74%    .Vectors.CheckFixedCbounds;  =0 (default): the bounds on C representation are min and max, =1: they are fixed by .Minc and .MaxC
75%    .Vectors.MinC = imposed minimum of the scalar field used for vector color;
76%    .Vectors.MaxC = imposed maximum of the scalar field used for vector color;
77%
78% PosColorbar: % if absent, no action on colorbar
79%              % if empty, suppress any existing colorbar
80%              % if not empty, display a colorbar for B&W images at position PosColorbar
81%                expressed in figure relative unit (ex [0.821 0.471 0.019 0.445])
82
83%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
84%  Copyright Joel Sommeria, 2008, LEGI / CNRS-UJF-INPG, sommeria@coriolis-legi.org.
85%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
86%     This file is part of the toolbox UVMAT.
87%
88%     UVMAT is free software; you can redistribute it and/or modify
89%     it under the terms of the GNU General Public License as published by
90%     the Free Software Foundation; either version 2 of the License, or
91%     (at your option) any later version.
92%
93%     UVMAT is distributed in the hope that it will be useful,
94%     but WITHOUT ANY WARRANTY; without even the implied warranty of
95%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
96%     GNU General Public License (file UVMAT/COPYING.txt) for more details.
97%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
98
99function [PlotType,PlotParamOut,haxes]= plot_field(Data,haxes,PlotParam,PosColorbar)
100
101%% default input and output
102if ~exist('PlotParam','var'),PlotParam=[];end;
103PlotType='text'; %default
104if ~isfield(PlotParam,'Coordinates')
105    PlotParam.Axes=[];
106    if isfield(Data,'CoordUnit')
107        PlotParam.Axes.CheckFixAspectRatio=1;
108        PlotParam.Axes.AspectRatio=1; %set axes equal by default if CoordUnit is defined
109    end
110end
111PlotParamOut=PlotParam;%default
112
113%% check input structure
114% check the cells of fields :
115[CellInfo,NbDimArray,errormsg]=find_field_cells(Data);
116if ~isempty(errormsg)
117    msgbox_uvmat('ERROR',['input of plot_field/find_field_cells: ' errormsg]);
118    return
119end
120
121index_3D=find(NbDimArray>2,1);
122if ~isempty(index_3D)
123    msgbox_uvmat('ERROR','volume plot not implemented yet');
124    return
125end
126index_2D=find(NbDimArray==2);%find 2D fields
127index_1D=find(NbDimArray==1);
128index_0D=find(NbDimArray==0);
129
130%% test axes and figure
131testnewfig=1;%test to create a new figure (default)
132testzoomaxes=0;%test for the existence of a zoom secondary figure attached to the plotting axes
133if exist('haxes','var')
134    if ishandle(haxes)
135        if isequal(get(haxes,'Type'),'axes')
136            testnewfig=0;
137            AxeData=get(haxes,'UserData');
138            if isfield(AxeData,'ZoomAxes')&& ishandle(AxeData.ZoomAxes)
139                if isequal(get(AxeData.ZoomAxes,'Type'),'axes')
140                    testzoomaxes=1;
141                    zoomaxes=AxeData.ZoomAxes;
142                end
143            end
144        end
145    end
146end
147
148%% create a new figure and axes if the plotting axes does not exist
149if testnewfig
150    hfig=figure;
151    set(hfig,'Units','normalized')
152    haxes=axes;
153    set(haxes,'position',[0.13,0.2,0.775,0.73])
154    PlotParamOut.NextPlot='add'; %parameter for plot_profile
155else
156    hfig=get(haxes,'parent');
157    set(0,'CurrentFigure',hfig)% the parent of haxes becomes the current figure
158    set(hfig,'CurrentAxes',haxes)%  haxes becomes the current axes of the parent figure
159end
160
161%% set axes properties
162if isfield(PlotParamOut.Axes,'CheckFixLimits') && isequal(PlotParamOut.Axes.CheckFixLimits,1)  %adjust the graph limits
163    set(haxes,'XLimMode', 'manual')
164    set(haxes,'YLimMode', 'manual')
165else
166    set(haxes,'XLimMode', 'auto')
167    set(haxes,'YLimMode', 'auto')
168end
169errormsg='';
170AxeData=get(haxes,'UserData');
171
172%% 2D plots
173if isempty(index_2D)
174    plot_plane([],[],haxes,[],[]);%removes images or vector plots in the absence of 2D field plot
175else  %plot 2D field
176    if ~exist('PosColorbar','var'),PosColorbar=[];end;
177    [tild,PlotParamOut,PlotType,errormsg]=plot_plane(Data,CellInfo(index_2D),haxes,PlotParamOut,PosColorbar);
178    AxeData.NbDim=2;
179    if testzoomaxes && isempty(errormsg)
180        [zoomaxes,PlotParamOut,tild,errormsg]=plot_plane(Data,CellInfo(index_2D),zoomaxes,PlotParamOut,PosColorbar);
181        AxeData.ZoomAxes=zoomaxes;
182    end
183end
184
185%% 1D plot (usual graph y vs x)
186if isempty(index_1D)
187    if ~isempty(haxes)
188        plot_profile([],[],haxes);%removes usual praphs y vs x in the absence of 1D field plot
189    end
190else %plot 1D field (usual graph y vs x)
191    CheckHold=0;
192    if isfield(PlotParam,'CheckHold')
193        CheckHold= PlotParam.CheckHold;
194    end       
195    PlotParamOut.Axes=plot_profile(Data,CellInfo(index_1D),haxes,PlotParamOut.Axes,CheckHold);%
196    if testzoomaxes
197        [zoomaxes,PlotParamOut.Axes]=plot_profile(Data,CellInfo(index_1D),zoomaxes,PlotParamOut.Axes,CheckHold);
198        AxeData.ZoomAxes=zoomaxes;
199    end
200    PlotType='line';
201end
202
203%% text display
204
205htext=findobj(hfig,'Tag','TableDisplay');
206hchecktable=findobj(hfig,'Tag','CheckTable');
207% if isempty(index_2D) && isempty(index_1D)%text display alone
208%     htext=findobj(hfig,'Tag','TableDisplay');
209% else  %text display added to plot
210%     %htext=findobj(hfig,'Tag','text_display');
211% end
212if ~isempty(htext)&&~isempty(hchecktable)
213    if isempty(index_0D)
214        set(htext,'Data',{})
215        set(htext,'visible','off')
216        set(hchecktable,'visible','off')
217        set(hchecktable,'Value',0)
218    else
219        errormsg=plot_text(Data,CellInfo(index_0D),htext);
220        set(htext,'visible','on')
221        set(hchecktable,'visible','on')
222        set(hchecktable,'Value',1)
223    end
224    set(hfig,'Unit','pixels');
225    set(htext,'Unit','pixels')
226    PosFig=get(hfig,'Position');
227    % case of no plot with view_field: only text display
228    if strcmp(get(hfig,'Tag'),'view_field')
229        if isempty(index_1D) && isempty(index_2D)% case of no plot: only text display
230            set(haxes,'Visible','off')         
231            PosTable=get(htext,'Position');
232            set(hfig,'Position',[PosFig(1) PosFig(2)  PosTable(3) PosTable(4)])
233        else
234            set(haxes,'Visible','on')
235            set(hfig,'Position',[PosFig(1) PosFig(2)  877 677])%default size for view_field
236        end
237    end
238end
239
240%% display error message
241if ~isempty(errormsg)
242    msgbox_uvmat('ERROR', errormsg)
243end
244
245%% update the parameters stored in AxeData
246if ishandle(haxes)&&( ~isempty(index_2D)|| ~isempty(index_1D))
247%     AxeData=[];
248    if isfield(PlotParamOut,'MinX')
249        AxeData.RangeX=[PlotParamOut.MinX PlotParamOut.MaxX];
250        AxeData.RangeY=[PlotParamOut.MinY PlotParamOut.MaxY];
251    end
252    set(haxes,'UserData',AxeData)
253end
254
255%% update the plotted field stored in parent figure
256if ~isempty(index_2D)|| ~isempty(index_1D)
257    FigData=get(hfig,'UserData');
258    if strcmp(get(hfig,'tag'),'view_field')||strcmp(get(hfig,'tag'),'uvmat')
259        FigData.(get(haxes,'tag'))=Data;
260        set(hfig,'UserData',FigData)
261    end
262end
263
264%-------------------------------------------------------------------
265% --- plot 0D fields: display data values without plot
266%------------------------------------------------------------------
267function errormsg=plot_text(FieldData,CellInfo,htext)
268
269errormsg='';
270txt_cell={};
271Data={};
272VarIndex=[];
273for icell=1:length(CellInfo)
274   
275    % select types of  variables to be projected
276    ListProj={'VarIndex_scalar','VarIndex_image','VarIndex_color','VarIndex_vector_x','VarIndex_vector_y'};
277    check_proj=false(size(FieldData.ListVarName));
278    for ilist=1:numel(ListProj)
279        if isfield(CellInfo{icell},ListProj{ilist})
280            check_proj(CellInfo{icell}.(ListProj{ilist}))=1;
281        end
282    end
283    VarIndex=[VarIndex find(check_proj)];
284end
285
286% data need to be displayed in a table
287if strcmp(get(htext,'Type'),'uitable')% display data in a table
288    VarNameCell=cell(1,numel(VarIndex));% prepare list of variable names to display (titles of columns)
289    VarLength=zeros(1,numel(VarIndex));  % default number of values for each variable
290    for ivar=1:numel(VarIndex)
291        VarNameCell{ivar}=FieldData.ListVarName{VarIndex(ivar)};
292        VarLength(ivar)=numel(FieldData.(VarNameCell{ivar}));
293    end
294    set(htext,'ColumnName',VarNameCell)
295    Data=cell(max(VarLength),numel(VarIndex));% prepare the table of data display
296   
297    for ivar=1:numel(VarIndex)
298        VarValue=FieldData.(VarNameCell{ivar});
299        VarValue=reshape(VarValue,[],1);% reshape values array in a column
300        Data(1:numel(VarValue),ivar)=num2cell(VarValue);
301    end
302    set(htext,'Data',Data)
303end
304%         if numel(VarValue)>1 && numel(VarValue)<10 % case of a variable with several values
305%             for ind=1:numel(VarValue)
306%                 VarNameCell{1,ind}=[VarName '_' num2str(ind)];% indicate each value by an index
307%             end
308%         else
309%             VarNameCell={VarName};
310%         end
311%         if numel(VarValue)<10
312%             if isempty(VarValue)
313%                 VarValueCell={'[]'};
314%             else
315%                 VarValueCell=num2cell(VarValue);
316%             end
317%             if isempty(Data)
318%                 Data =[VarNameCell VarValueCell];
319%             else
320%                 Data =[Data [VarNameCell VarValueCell]];
321%             end
322%         else
323%             if isempty(Data)
324%                 Data =[VarNameCell; num2cell(VarValue)];
325%             else
326%                 Data =[Data [VarNameCell; {['size ' num2str(size(VarValue))]}]];
327%             end
328%         end
329%         if size(VarValue,1)==1
330%             txt=[VarName '=' num2str(VarValue)];
331%             txt_cell=[txt_cell;{txt}];
332%         end
333%     end
334% end
335% if strcmp(get(htext,'Type'),'uitable')% display data in a table
336%
337
338%     set(htext,'Data',Data(2:end,:))
339% else  % display in a text edit box
340%     set(htext,'String',txt_cell)
341%     set(htext,'UserData',txt_cell)% for temporary storage when the edit box is used for mouse display
342% end
343
344
345%-------------------------------------------------------------------
346% --- plot 1D fields (usual x,y plots)
347%-------------------------------------------------------------------
348function CoordinatesOut=plot_profile(data,CellInfo,haxes,Coordinates,CheckHold)
349
350%% initialization
351if ~exist('Coordinates','var')
352    Coordinates=[];
353end
354CoordinatesOut=Coordinates; %default
355hfig=get(haxes,'parent');
356legend_str={};
357
358%% suppress existing plot if empty data
359if isempty(data)
360    hplot=findobj(haxes,'tag','plot_line');
361    if ~isempty(hplot)
362        delete(hplot)
363    end
364    hlegend=findobj(hfig,'tag','legend');
365    if ~isempty(hlegend)
366        delete(hlegend)
367    end
368    return
369end
370
371%% set the colors of the successive plots (designed to produce rgb for the three components of color images)
372ColorOrder=[1 0 0;0 1 0;0 0 1;0 0.75 0.75;0.75 0 0.75;0.75 0.75 0;0.25 0.25 0.25];
373set(hfig,'DefaultAxesColorOrder',ColorOrder)
374% if isfield(Coordinates,'NextPlot')
375%     set(haxes,'NextPlot',Coordinates.NextPlot)
376% end
377if CheckHold
378    set(haxes,'NextPlot','add')
379else
380    set(haxes,'NextPlot','replace')
381end
382
383%% prepare the string for plot command
384plotstr='hhh=plot(';
385% coord_x_index=[];
386xtitle='';
387ytitle='';
388test_newplot=~CheckHold;
389MinX=[];
390MaxX=[];
391MinY_cell=[];
392MaxY_cell=[];
393%loop on input  fields
394for icell=1:numel(CellInfo)
395    VarIndex=CellInfo{icell}.VarIndex;%  indices of the selected variables in the list data.ListVarName
396    coord_x_index=CellInfo{icell}.CoordIndex;
397    testplot=ones(size(data.ListVarName));%default test for plotted variables
398    coord_x_name{icell}=data.ListVarName{coord_x_index};
399    coord_x{icell}=data.(data.ListVarName{coord_x_index});%coordinate variable set as coord_x
400    if isempty(find(strcmp(coord_x_name{icell},coord_x_name(1:end-1)), 1)) %xtitle not already selected
401        xtitle=[xtitle coord_x_name{icell}];
402        if isfield(data,'VarAttribute')&& numel(data.VarAttribute)>=coord_x_index && isfield(data.VarAttribute{coord_x_index},'units')
403            xtitle=[xtitle '(' data.VarAttribute{coord_x_index}.units '), '];
404        else
405            xtitle=[xtitle ', '];
406        end
407    end
408    if ~isempty(coord_x{icell})
409        MinX(icell)=min(coord_x{icell});
410        MaxX(icell)=max(coord_x{icell});
411        testplot(coord_x_index)=0;
412        if isfield(CellInfo{icell},'VarIndex_ancillary')
413            testplot(CellInfo{icell}.VarIndex_ancillary)=0;
414        end
415        if isfield(CellInfo{icell},'VarIndex_warnflag')
416            testplot(CellInfo{icell}.VarIndex_warnflag)=0;
417        end
418        if isfield(data,'VarAttribute')
419            VarAttribute=data.VarAttribute;
420            for ivar=1:length(VarIndex)
421                if length(VarAttribute)>=VarIndex(ivar) && isfield(VarAttribute{VarIndex(ivar)},'long_name')
422                    plotname{VarIndex(ivar)}=VarAttribute{VarIndex(ivar)}.long_name;
423                else
424                    plotname{VarIndex(ivar)}=data.ListVarName{VarIndex(ivar)};%name for display in plot A METTRE
425                end
426            end
427        end
428        if isfield(CellInfo{icell},'VarIndex_discrete')
429            charplot_0='''+''';
430        else
431            charplot_0='''-''';
432        end
433        MinY=[];
434        MaxY=[];%default
435       
436        nbplot=0;
437        for ivar=1:length(VarIndex)
438            if testplot(VarIndex(ivar))
439                VarName=data.ListVarName{VarIndex(ivar)};
440                nbplot=nbplot+1;
441                ytitle=[ytitle VarName];
442                if isfield(data,'VarAttribute')&& numel(data.VarAttribute)>=VarIndex(ivar) && isfield(data.VarAttribute{VarIndex(ivar)},'units')
443                    ytitle=[ytitle '(' data.VarAttribute{VarIndex(ivar)}.units '), '];
444                else
445                    ytitle=[ytitle ', '];
446                end
447                eval(['data.' VarName '=squeeze(data.' VarName ');'])
448                MinY(ivar)=min(min(data.(VarName)));
449                MaxY(ivar)=max(max(data.(VarName)));
450                plotstr=[plotstr 'coord_x{' num2str(icell) '},data.' VarName ',' charplot_0 ','];
451                eval(['nbcomponent2=size(data.' VarName ',2);']);
452                eval(['nbcomponent1=size(data.' VarName ',1);']);
453                if numel(coord_x{icell})==2
454                    coord_x{icell}=linspace(coord_x{icell}(1),coord_x{icell}(2),nbcomponent1);
455                end
456                if nbcomponent1==1|| nbcomponent2==1
457                    legend_str=[legend_str {VarName}]; %variable with one component
458                else  %variable with severals  components
459                    for ic=1:min(nbcomponent1,nbcomponent2)
460                        legend_str=[legend_str [VarName '_' num2str(ic)]]; %variable with severals  components
461                    end                                                   % labeled by their index (e.g. color component)
462                end
463            end
464        end
465        if ~isempty(MinY)
466            MinY_cell(icell)=min(MinY);
467            MaxY_cell(icell)=max(MaxY);
468        end
469    end
470end
471
472%% activate the plot
473if  ~isequal(plotstr,'hhh=plot(') 
474    set(hfig,'CurrentAxes',haxes)
475    tag=get(haxes,'tag');   
476    %%%
477    plotstr=[plotstr '''tag'',''plot_line'');'];   
478    eval(plotstr)                  %execute plot (instruction  plotstr)
479    %%%
480    set(haxes,'tag',tag)% restitute the axes tag (removed by the command plot)
481    set(haxes,'ColorOrder',ColorOrder)% restitute the plot color order (to get red green blue for histograms or cuts of color images)
482    grid(haxes, 'on')
483    hxlabel=xlabel(xtitle(1:end-2));% xlabel (removes ', ' at the end)
484    set(hxlabel,'Interpreter','none')% desable tex interpreter
485    if length(legend_str)>=1
486        hylabel=ylabel(ytitle(1:end-2));% ylabel (removes ', ' at the end)
487        set(hylabel,'Interpreter','none')% desable tex interpreter
488    end
489    if ~isempty(legend_str)
490        hlegend=findobj(hfig,'Tag','legend');
491        if isempty(hlegend)
492            hlegend=legend(legend_str);
493            txt=ver('MATLAB');
494            Release=txt.Release;
495            relnumb=str2double(Release(3:4));% should be changed to Version for better compatibility
496            if relnumb >= 14
497                set(hlegend,'Interpreter','none')% desable tex interpreter
498            end
499        else
500            legend_old=get(hlegend,'String');
501            if isequal(size(legend_old,1),size(legend_str,1))&&~isequal(legend_old,legend_str)
502                set(hlegend,'String',[legend_old legend_str]);
503            end
504        end
505    end
506    title_str='';
507    if isfield(data,'filename')
508       [Path, title_str, ext]=fileparts(data.filename);
509       title_str=[title_str ext];
510    end
511    if isfield(data,'Action')&&isfield(data.Action,'ActionName')
512        if ~isequal(title_str,'')
513            title_str=[title_str ', '];
514        end
515        title_str=[title_str data.Action.ActionName];
516    end
517    htitle=title(title_str);
518    set(htitle,'Interpreter','none')% desable tex interpreter
519end
520
521%% determine axes bounds
522fix_lim=isfield(Coordinates,'CheckFixLimits') && Coordinates.CheckFixLimits;
523check_lim=isfield(Coordinates,'MinX')&&isfield(Coordinates,'MaxX')&&isfield(Coordinates,'MinY')&&isfield(Coordinates,'MaxY');
524if fix_lim
525    if ~check_lim
526        fix_lim=0; %free limits if limits are not set,
527    end
528end
529if fix_lim
530    set(haxes,'XLim',[Coordinates.MinX Coordinates.MaxX])
531    set(haxes,'YLim',[Coordinates.MinY Coordinates.MaxY])
532else
533    if ~isempty(MinX)
534        if check_lim
535            CoordinatesOut.MinX=min(min(MinX),CoordinatesOut.MinX);
536            CoordinatesOut.MaxX=max(max(MaxX),CoordinatesOut.MaxX);
537        else
538            CoordinatesOut.MinX=min(MinX);
539            CoordinatesOut.MaxX=max(MaxX);
540        end
541    end
542    if ~isempty(MinY_cell)
543        if check_lim
544            CoordinatesOut.MinY=min(min(MinY_cell),CoordinatesOut.MinY);
545            CoordinatesOut.MaxY=max(max(MaxY_cell),CoordinatesOut.MaxY);
546        else
547            CoordinatesOut.MinY=min(MinY_cell);
548            CoordinatesOut.MaxY=max(MaxY_cell);
549        end
550    end
551end
552
553%% determine plot aspect ratio
554if isfield(Coordinates,'CheckFixAspectRatio') && isequal(Coordinates.CheckFixAspectRatio,1)&&isfield(Coordinates,'AspectRatio')
555    set(haxes,'DataAspectRatioMode','manual')
556    set(haxes,'DataAspectRatio',[Coordinates.AspectRatio 1 1])
557else
558    set(haxes,'DataAspectRatioMode','auto')%automatic aspect ratio
559    AspectRatio=get(haxes,'DataAspectRatio');
560    CoordinatesOut.AspectRatio=AspectRatio(1)/AspectRatio(2);
561end
562
563%-------------------------------------------------------------------
564function [haxes,PlotParamOut,PlotType,errormsg]=plot_plane(Data,CellInfo,haxes,PlotParam,PosColorbar)
565%-------------------------------------------------------------------
566PlotType='plane';
567grid(haxes, 'off')% remove grid (possibly remaining from other graphs)
568
569%default plotting parameters
570if ~isfield(PlotParam,'Scalar')
571    PlotParam.Scalar=[];
572end
573if ~isfield(PlotParam,'Vectors')
574    PlotParam.Vectors=[];
575end
576PlotParamOut=PlotParam;%default
577errormsg='';%default
578
579hfig=get(haxes,'parent');%handle of the figure containing the plot axes
580hcol=findobj(hfig,'Tag','Colorbar'); %look for colorbar axes
581hima=findobj(haxes,'Tag','ima');% search existing image in the current axes
582test_ima=0; %default: test for image or map plot
583test_vec=0; %default: test for vector plots
584test_black=0;
585test_false=0;
586test_C=0;
587XName='';
588x_units='';
589YName='';
590y_units='';
591
592% loop on the input field cells
593for icell=1:numel(CellInfo)
594    if strcmp(CellInfo{icell}.CoordType,'tps') %do not plot directly tps data (used for projection only)
595        continue
596    end
597    ivar_X=CellInfo{icell}.CoordIndex(end); % defines (unique) index for the variable representing unstructured x coordinate (default =[])
598    ivar_Y=CellInfo{icell}.CoordIndex(end-1); % defines (unique)index for the variable representing unstructured y coordinate (default =[])
599    ivar_C=[];
600    if isfield(CellInfo{icell},'VarIndex_scalar')
601        ivar_C=[ivar_C CellInfo{icell}.VarIndex_scalar];
602    end
603    if isfield(CellInfo{icell},'VarIndex_image')
604        ivar_C=[ivar_C CellInfo{icell}.VarIndex_image];
605    end
606    if isfield(CellInfo{icell},'VarIndex_color')
607        ivar_C=[ivar_C CellInfo{icell}.VarIndex_color];
608    end
609    if isfield(CellInfo{icell},'VarIndex_ancillary')
610        ivar_C=[ivar_C CellInfo{icell}.VarIndex_ancillary];
611    end
612    if numel(ivar_C)>1
613        errormsg= 'error in plot_field: too many scalar inputs';
614        return
615    end
616    ivar_F=[];
617    if isfield(CellInfo{icell},'VarIndex_warnflag')
618        ivar_F=CellInfo{icell}.VarIndex_warnflag; %defines index (unique) for warning flag variable
619    end
620    ivar_FF_vec=[];
621    if isfield(CellInfo{icell},'VarIndex_vector_x')&&isfield(CellInfo{icell},'VarIndex_vector_y') % vector components detected
622        if test_vec% a vector field has been already detected
623            errormsg='error in plot_field: attempt to plot two vector fields: to get the difference project on a plane with mode interp';
624            return
625        else
626            test_vec=1;
627            if isfield(CellInfo{icell},'VarIndex_errorflag')
628                ivar_FF_vec=CellInfo{icell}.VarIndex_errorflag; %defines index (unique) for error flag variable
629            end
630            vec_U=Data.(Data.ListVarName{CellInfo{icell}.VarIndex_vector_x});
631            vec_V=Data.(Data.ListVarName{CellInfo{icell}.VarIndex_vector_y});
632            if strcmp(CellInfo{icell}.CoordType,'scattered')%2D field with unstructured coordinates
633                XName=Data.ListVarName{CellInfo{icell}.CoordIndex(end)};
634                YName=Data.ListVarName{CellInfo{icell}.CoordIndex(end-1)};
635                vec_X=reshape(Data.(XName),[],1); %transform vectors in column matlab vectors
636                vec_Y=reshape(Data.(YName),[],1);
637            elseif strcmp(CellInfo{icell}.CoordType,'grid')%2D field with structured coordinates
638                y=Data.(Data.ListVarName{CellInfo{icell}.CoordIndex(end-1)});
639                x=Data.(Data.ListVarName{CellInfo{icell}.CoordIndex(end)});
640                if numel(y)==2 % y defined by first and last values on aregular mesh
641                    y=linspace(y(1),y(2),size(vec_U,1));
642                end
643                if numel(x)==2 % y defined by first and last values on aregular mesh
644                    x=linspace(x(1),x(2),size(vec_U,2));
645                end
646                [vec_X,vec_Y]=meshgrid(x,y);
647            end
648            if isfield(PlotParam.Vectors,'ColorScalar') && ~isempty(PlotParam.Vectors.ColorScalar)
649                [VarVal,ListVarName,VarAttribute,errormsg]=calc_field_interp([],Data,PlotParam.Vectors.ColorScalar);
650                if ~isempty(VarVal)
651                    vec_C=reshape(VarVal{1},1,numel(VarVal{1}));
652                    test_C=1;
653                end
654            end
655            if ~isempty(ivar_F)%~(isfield(PlotParam.Vectors,'HideWarning')&& isequal(PlotParam.Vectors.HideWarning,1))
656%                 if test_vec
657                    vec_F=Data.(Data.ListVarName{ivar_F}); % warning flags for  dubious vectors
658                    if  ~(isfield(PlotParam.Vectors,'CheckHideWarning') && isequal(PlotParam.Vectors.CheckHideWarning,1))
659                        test_black=1;
660                    end
661%                 end
662            end
663            if ~isempty(ivar_FF_vec) %&& ~test_false
664%                 if test_vec% TODO: deal with FF for structured coordinates
665                    vec_FF=Data.(Data.ListVarName{ivar_FF_vec}); % flags for false vectors
666%                 end
667            end
668        end
669    elseif ~isempty(ivar_C) %scalar or image
670        if test_ima
671            errormsg='attempt to plot two scalar fields or images';
672            return
673        end
674        A=squeeze(Data.(Data.ListVarName{ivar_C}));% scalar represented as color image
675        test_ima=1;
676        if strcmp(CellInfo{icell}.CoordType,'scattered')%2D field with unstructured coordinates
677            A=reshape(A,1,[]);
678            XName=Data.ListVarName{ivar_X};
679            YName=Data.ListVarName{ivar_Y};
680            eval(['AX=reshape(Data.' XName ',1,[]);'])
681            eval(['AY=reshape(Data.' YName ',1,[]);'])
682            [A,AX,AY]=proj_grid(AX',AY',A',[],[],'np>256');  % interpolate on a grid
683            if isfield(Data,'VarAttribute')
684                if numel(Data.VarAttribute)>=ivar_X && isfield(Data.VarAttribute{ivar_X},'units')
685                    x_units=[' (' Data.VarAttribute{ivar_X}.units ')'];
686                end
687                if numel(Data.VarAttribute)>=ivar_Y && isfield(Data.VarAttribute{ivar_Y},'units')
688                    y_units=[' (' Data.VarAttribute{ivar_Y}.units ')'];
689                end
690            end
691        elseif strcmp(CellInfo{icell}.CoordType,'grid')%2D field with structured coordinates
692            YName=Data.ListVarName{CellInfo{icell}.CoordIndex(end-1)};
693            AY=Data.(YName);
694            AX=Data.(Data.ListVarName{CellInfo{icell}.CoordIndex(end)});
695            test_interp_X=0; %default, regularly meshed X coordinate
696            test_interp_Y=0; %default, regularly meshed Y coordinate
697            if isfield(Data,'VarAttribute')
698                if numel(Data.VarAttribute)>=CellInfo{icell}.CoordIndex(end) && isfield(Data.VarAttribute{CellInfo{icell}.CoordIndex(end)},'units')
699                    x_units=Data.VarAttribute{CellInfo{icell}.CoordIndex(end)}.units;
700                end
701                if numel(Data.VarAttribute)>=CellInfo{icell}.CoordIndex(end-1) && isfield(Data.VarAttribute{CellInfo{icell}.CoordIndex(end-1)},'units')
702                    y_units=Data.VarAttribute{CellInfo{icell}.CoordIndex(end-1)}.units;
703                end
704            end
705            if numel(AY)>2
706                DAY=diff(AY);
707                DAY_min=min(DAY);
708                DAY_max=max(DAY);
709                if sign(DAY_min)~=sign(DAY_max);% =1 for increasing values, 0 otherwise
710                    errormsg=['errror in plot_field.m: non monotonic dimension variable ' Data.ListVarName{VarRole.coord(1)} ];
711                    return
712                end
713                test_interp_Y=(DAY_max-DAY_min)> 0.0001*abs(DAY_max);
714            end
715            if numel(AX)>2
716                DAX=diff(AX);
717                DAX_min=min(DAX);
718                DAX_max=max(DAX);
719                if sign(DAX_min)~=sign(DAX_max);% =1 for increasing values, 0 otherwise
720                    errormsg=['errror in plot_field.m: non monotonic dimension variable ' Data.ListVarName{VarRole.coord(2)} ];
721                    return
722                end
723                test_interp_X=(DAX_max-DAX_min)> 0.0001*abs(DAX_max);
724            end
725            if test_interp_Y
726                npxy(1)=max([256 floor((AY(end)-AY(1))/DAY_min) floor((AY(end)-AY(1))/DAY_max)]);
727                yI=linspace(AY(1),AY(end),npxy(1));
728                if ~test_interp_X
729                    xI=linspace(AX(1),AX(end),size(A,2));%default
730                    AX=xI;
731                end
732            end
733            if test_interp_X
734                npxy(2)=max([256 floor((AX(end)-AX(1))/DAX_min) floor((AX(end)-AX(1))/DAX_max)]);
735                xI=linspace(AX(1),AX(end),npxy(2));
736                if ~test_interp_Y
737                    yI=linspace(AY(1),AY(end),size(A,1));
738                    AY=yI;
739                end
740            end
741            if test_interp_X || test_interp_Y
742                [AX2D,AY2D]=meshgrid(AX,AY);
743                A=interp2(AX2D,AY2D,double(A),xI,yI');
744            end
745            AX=[AX(1) AX(end)];% keep only the lower and upper bounds for image represnetation
746            AY=[AY(1) AY(end)];
747        end
748    end
749    %define coordinates as CoordUnits, if not defined as attribute for each variable
750    if isfield(Data,'CoordUnit')
751        if isempty(x_units)
752            x_units=Data.CoordUnit;
753        end
754        if isempty(y_units)
755            y_units=Data.CoordUnit;
756        end
757    end   
758end
759PlotParamOut=PlotParam; % output plot parameters equal to input by default
760
761%%   image or scalar plot %%%%%%%%%%%%%%%%%%%%%%%%%%
762if test_ima
763   
764    % distinguish B/W and color images
765    np=size(A);%size of image
766    siz=numel(np);
767    if siz>3
768        errormsg=['unrecognized scalar type: ' num2str(siz) ' dimensions'];
769        return
770    end
771    if siz==3
772        if np(3)==1
773            siz=2;%B W image
774        elseif np(3)==3
775            siz=3;%color image
776        else
777            errormsg=['unrecognized scalar type in plot_field: considered as 2D field with ' num2str(np(3)) ' color components'];
778            return
779        end
780    end
781   
782    %set the color map
783    if isfield(PlotParam.Scalar,'CheckBW') && ~isempty(PlotParam.Scalar.CheckBW)
784        BW=PlotParam.Scalar.CheckBW; %BW=0 color imposed, else gray scale imposed.
785    else % BW imposed automatically chosen
786        BW=(siz==2) && (isa(A,'uint8')|| isa(A,'uint16'));% non color images represented in gray scale by default
787        PlotParamOut.Scalar.CheckBW=BW;
788    end
789   
790            % determine the plot option 'image' or 'contours'
791    if isfield(PlotParam.Scalar,'ListContour')
792        CheckContour=strcmp(PlotParam.Scalar.ListContour,'contours');% =1 for contour plot option
793    else
794        CheckContour=0; %default
795    end
796   
797    %case of grey level images or contour plot
798    if siz==2
799        if ~isfield(PlotParam.Scalar,'CheckFixScalar')
800            PlotParam.Scalar.CheckFixScalar=0;% free scalar threshold value scale (from min to max) by default
801        end
802        if ~isfield(PlotParam.Scalar,'MinA')
803            PlotParam.Scalar.MinA=[];%no min scalar threshold value set
804        end
805        if ~isfield(PlotParam.Scalar,'MaxA')
806            PlotParam.Scalar.MaxA=[];%no max scalar threshold value set
807        end
808       
809        % determine the min scalar value
810        if PlotParam.Scalar.CheckFixScalar && ~isempty(PlotParam.Scalar.MinA) && isnumeric(PlotParam.Scalar.MinA) 
811            MinA=double(PlotParam.Scalar.MinA); % min value set as input
812        else
813            MinA=double(min(min(A))); % min value set as min of non NaN scalar values
814        end
815       
816        % error if the input scalar is NaN everywhere
817        if isnan(MinA)
818                errormsg='NaN input scalar or image in plot_field';
819                return
820        end
821       
822        % determine the max scalar value
823        if PlotParam.Scalar.CheckFixScalar && ~isempty(PlotParam.Scalar.MaxA) && isnumeric(PlotParam.Scalar.MaxA) 
824            MaxA=double(PlotParam.Scalar.MaxA); % max value set as input
825        else
826            MaxA=double(max(max(A))); % max value set as min of non NaN scalar values
827        end
828       
829        PlotParamOut.Scalar.MinA=MinA;
830        PlotParamOut.Scalar.MaxA=MaxA;
831        PlotParamOut.Scalar.Npx=size(A,2);
832        PlotParamOut.Scalar.Npy=size(A,1);
833       
834        % case of contour plot
835        if CheckContour
836            if ~isempty(hima) && ishandle(hima)
837                delete(hima) % delete existing image
838            end
839           
840            % set the contour values
841            if ~isfield(PlotParam.Scalar,'IncrA')
842                PlotParam.Scalar.IncrA=[];% automatic contour interval
843            end
844            if ~isempty(PlotParam.Scalar.IncrA) && isnumeric(PlotParam.Scalar.IncrA)
845                interval=PlotParam.Scalar.IncrA;
846            else % automatic contour interval
847                cont=colbartick(MinA,MaxA);
848                interval=cont(2)-cont(1);%default
849                PlotParamOut.Scalar.IncrA=interval;% set the interval as output for display on the GUI
850            end
851            %B=A;
852            abscontmin=interval*floor(MinA/interval);
853            abscontmax=interval*ceil(MaxA/interval);
854            contmin=interval*floor(min(min(A))/interval);
855            contmax=interval*ceil(max(max(A))/interval);
856            cont_pos_plus=0:interval:contmax;% zero and positive contour values (plotted as solid lines)
857            cont_pos_min=double(contmin):interval:-interval;% negative contour values (plotted as dashed lines)
858            cont_pos=[cont_pos_min cont_pos_plus];% set of all contour values
859           
860            sizpx=(AX(end)-AX(1))/(np(2)-1);
861            sizpy=(AY(1)-AY(end))/(np(1)-1);
862            x_cont=AX(1):sizpx:AX(end); % pixel x coordinates for image display
863            y_cont=AY(1):-sizpy:AY(end); % pixel x coordinates for image display
864           
865            %axes(haxes)% set the input axes handle as current axis
866
867           % colormap(map);
868           tag_axes=get(haxes,'Tag');% axes tag
869           Opacity=1;
870           if isfield(PlotParam.Scalar,'Opacity')&&~isempty(PlotParam.Scalar.Opacity)
871               Opacity=PlotParam.Scalar.Opacity;
872           end
873           % fill the space between contours if opacity is undefined or =1
874           if isequal(Opacity,1)
875               [var,hcontour]=contour(haxes,x_cont,y_cont,A,cont_pos);% determine all contours
876               set(hcontour,'Fill','on')% fill the space between contours
877               set(hcontour,'LineStyle','none')
878               hold on
879           end
880           [var_p,hcontour_p]=contour(haxes,x_cont,y_cont,A,cont_pos_plus,'k-');% draw the contours for positive values as solid lines
881           hold on
882           [var_m,hcontour_m]=contour(haxes,x_cont,y_cont,A,cont_pos_min,'--');% draw the contours for negative values as dashed lines
883           if isequal(Opacity,1)
884               set(hcontour_m,'LineColor',[1 1 1])% draw negative contours in white (better visibility in dark background)
885           end
886           set(haxes,'Tag',tag_axes);% restore axes tag (removed by the matlab fct contour !)
887           hold off
888           
889            %determine the color scale and map
890            caxis([abscontmin abscontmax])
891            if BW
892                vec=linspace(0,1,(abscontmax-abscontmin)/interval);%define a greyscale colormap with steps interval
893                map=[vec' vec' vec'];
894                colormap(map);
895            else
896                colormap('default'); % default matlab colormap ('jet')
897            end
898           
899            if isfield(PlotParam.Axes,'CheckFixAspectRatio') && isequal(PlotParam.Axes.CheckFixAspectRatio,1)
900                set(haxes,'DataAspectRatioMode','manual')
901                if isfield(PlotParam.Axes,'AspectRatio')
902                    set(haxes,'DataAspectRatio',[PlotParam.Axes.AspectRatio 1 1])
903                else
904                    set(haxes,'DataAspectRatio',[1 1 1])
905                end
906            end
907        else     
908        % set  colormap for  image display
909            % rescale the grey levels with min and max, put a grey scale colorbar
910%             B=A;
911            if BW
912                vec=linspace(0,1,255);%define a linear greyscale colormap
913                map=[vec' vec' vec'];
914                colormap(map);  %grey scale color map
915            else
916                colormap('default'); % standard false colors for div, vort , scalar fields
917            end
918        end
919       
920        % case of color images
921    else
922        if BW
923            A=uint16(sum(A,3));
924        else
925            A=uint8(A);
926        end
927        MinA=0;
928        MaxA=255;
929    end
930   
931    % display usual image
932    if ~CheckContour
933        % interpolate field to increase resolution of image display
934        test_interp=0;
935        if size(A,3)==1 % scalar of B/W image
936            test_interp=1;
937            if max(np) <= 64
938                npxy=8*np;% increase the resolution 8 times
939            elseif max(np) <= 128
940                npxy=4*np;% increase the resolution 4 times
941            elseif max(np) <= 256
942                npxy=2*np;% increase the resolution 2 times
943            else
944                npxy=np;
945                test_interp=0; % no interpolation done
946            end
947        end
948        if test_interp%if we interpolate
949            x=linspace(AX(1),AX(2),np(2));
950            y=linspace(AY(1),AY(2),np(1));
951            [X,Y]=meshgrid(x,y);
952            xi=linspace(AX(1),AX(2),npxy(2));
953            yi=linspace(AY(1),AY(2),npxy(1));
954            A = interp2(X,Y,double(A),xi,yi');
955        end
956        % create new image if there  no image handle is found
957        if isempty(hima)
958            tag=get(haxes,'Tag');
959            if MinA<MaxA
960                hima=imagesc(AX,AY,A,[MinA MaxA]);
961            else % to deal with uniform field
962                hima=imagesc(AX,AY,A,[MaxA-1 MaxA]);
963            end
964            % the function imagesc reset the axes 'DataAspectRatioMode'='auto', change if .CheckFixAspectRatio is
965            % requested:
966            set(hima,'Tag','ima')
967            set(hima,'HitTest','off')
968            set(haxes,'Tag',tag);%preserve the axes tag (removed by image fct !!!)
969            uistack(hima, 'bottom')
970            % update an existing image
971        else
972            set(hima,'CData',A);
973            if MinA<MaxA
974                set(haxes,'CLim',[MinA MaxA])
975            else
976                set(haxes,'CLim',[MinA MaxA+1])
977            end
978            set(hima,'XData',AX);
979            set(hima,'YData',AY);
980        end
981       
982        % set the transparency to 0.5 if vectors are also plotted
983        if isfield(PlotParam.Scalar,'Opacity')&& ~isempty(PlotParam.Scalar.Opacity)
984            set(hima,'AlphaData',PlotParam.Scalar.Opacity)
985        else
986            if test_vec
987                set(hima,'AlphaData',0.5)%set opacity to 0.5 by default in the presence of vectors
988                PlotParamOut.Scalar.Opacity=0.5;
989            else
990                set(hima,'AlphaData',1)% full opacity (no transparency) by default
991            end
992        end
993    end
994    test_ima=1;
995   
996    %display the colorbar code for B/W images if Poscolorbar not empty
997    if ~isempty(PosColorbar)
998        if siz==2 && exist('PosColorbar','var')
999            if isempty(hcol)||~ishandle(hcol)
1000                hcol=colorbar;%create new colorbar
1001            end
1002            if length(PosColorbar)==4
1003                set(hcol,'Position',PosColorbar)
1004            end
1005            %YTick=0;%default
1006            if MaxA>MinA
1007                if CheckContour
1008                    colbarlim=get(hcol,'YLim');
1009                    scale_bar=(colbarlim(2)-colbarlim(1))/(abscontmax-abscontmin);
1010                    YTick=cont_pos(2:end-1);
1011                    YTick_scaled=colbarlim(1)+scale_bar*(YTick-abscontmin);
1012                    set(hcol,'YTick',YTick_scaled);
1013                elseif (isfield(PlotParam.Scalar,'CheckBW') && isequal(PlotParam.Scalar.CheckBW,1))||isa(A,'uint8')|| isa(A,'uint16')%images
1014                    hi=get(hcol,'children');
1015                    if iscell(hi)%multiple images in colorbar
1016                        hi=hi{1};
1017                    end
1018                    set(hi,'YData',[MinA MaxA])
1019                    set(hi,'CData',(1:256)')
1020                    set(hcol,'YLim',[MinA MaxA])
1021                    YTick=colbartick(MinA,MaxA);
1022                    set(hcol,'YTick',YTick)
1023                else
1024                    hi=get(hcol,'children');
1025                    if iscell(hi)%multiple images in colorbar
1026                        hi=hi{1};
1027                    end
1028                    set(hi,'YData',[MinA MaxA])
1029                    set(hi,'CData',(1:64)')
1030                    YTick=colbartick(MinA,MaxA);
1031                    set(hcol,'YLim',[MinA MaxA])
1032                    set(hcol,'YTick',YTick)
1033                end
1034                set(hcol,'Yticklabel',num2str(YTick'));
1035            end
1036        elseif ishandle(hcol)
1037            delete(hcol); %erase existing colorbar if not needed
1038        end
1039    end
1040else%no scalar plot
1041    if ~isempty(hima) && ishandle(hima)
1042        delete(hima)
1043    end
1044    if ~isempty(PosColorbar) && ~isempty(hcol)&& ishandle(hcol)
1045        delete(hcol)
1046    end
1047    PlotParamOut=rmfield(PlotParamOut,'Scalar');
1048end
1049
1050%%   vector plot %%%%%%%%%%%%%%%%%%%%%%%%%%
1051if test_vec
1052   %vector scale representation
1053    if size(vec_U,1)==numel(vec_Y) && size(vec_U,2)==numel(vec_X); % x, y  coordinate variables
1054        [vec_X,vec_Y]=meshgrid(vec_X,vec_Y);
1055    end   
1056    vec_X=reshape(vec_X,1,numel(vec_X));%reshape in matlab vectors
1057    vec_Y=reshape(vec_Y,1,numel(vec_Y));
1058    vec_U=reshape(vec_U,1,numel(vec_U));
1059    vec_V=reshape(vec_V,1,numel(vec_V));
1060     MinMaxX=max(vec_X)-min(vec_X);
1061    if  isfield(PlotParam.Vectors,'CheckFixVectors') && isequal(PlotParam.Vectors.CheckFixVectors,1)&& isfield(PlotParam.Vectors,'VecScale')...
1062               &&~isempty(PlotParam.Vectors.VecScale) && isa(PlotParam.Vectors.VecScale,'double') %fixed vector scale
1063        scale=PlotParam.Vectors.VecScale;  %impose the length of vector representation
1064    else
1065        if ~test_false %remove false vectors   
1066            indsel=1:numel(vec_X);%
1067        end
1068        if isempty(vec_U)
1069            scale=1;
1070        else
1071            if isempty(indsel)
1072                MaxU=max(abs(vec_U));
1073                MaxV=max(abs(vec_V));
1074            else
1075                MaxU=max(abs(vec_U(indsel)));
1076                MaxV=max(abs(vec_V(indsel)));
1077            end
1078            scale=MinMaxX/(max(MaxU,MaxV)*50);
1079            PlotParam.Vectors.VecScale=scale;%update the 'scale' display
1080        end
1081    end
1082   
1083    %record vectors on the plotting axes
1084    if test_C==0
1085        vec_C=ones(1,numel(vec_X));
1086    end
1087   
1088    %decimate by a factor 2 in vector mesh(4 in nbre of vectors)
1089    check_decimate=0;
1090    if isfield(PlotParam.Vectors,'CheckDecimate4') && PlotParam.Vectors.CheckDecimate4
1091        check_decimate=1;
1092        diffy=diff(vec_Y); %difference dy=vec_Y(i+1)-vec_Y(i)
1093        dy_thresh=max(abs(diffy))/2;
1094        ind_jump=find(abs(diffy) > dy_thresh); %indices with diff(vec_Y)> max/2, detect change of line
1095        ind_sel=1:ind_jump(1);%select the first line
1096        for i=2:2:length(ind_jump)-1
1097            ind_sel=[ind_sel (ind_jump(i)+1:ind_jump(i+1))];% select the odd lines
1098        end
1099        nb_sel=length(ind_sel);
1100        ind_sel=ind_sel(1:2:nb_sel);% take half the points on a line
1101    elseif isfield(PlotParam.Vectors,'CheckDecimate16') && PlotParam.Vectors.CheckDecimate16
1102        check_decimate=1;
1103        diffy=diff(vec_Y); %difference dy=vec_Y(i+1)-vec_Y(i)
1104        dy_thresh=max(abs(diffy))/2;
1105        ind_jump=find(abs(diffy) > dy_thresh); %indices with diff(vec_Y)> max/2, detect change of line
1106        ind_sel=1:ind_jump(1);%select the first line
1107        for i=2:4:length(ind_jump)-1
1108            ind_sel=[ind_sel (ind_jump(i)+1:ind_jump(i+1))];% select the odd lines
1109        end
1110        nb_sel=length(ind_sel);
1111        ind_sel=ind_sel(1:4:nb_sel);% take half the points on a line
1112    end
1113    if check_decimate
1114        vec_X=vec_X(ind_sel);
1115        vec_Y=vec_Y(ind_sel);
1116        vec_U=vec_U(ind_sel);
1117        vec_V=vec_V(ind_sel);
1118        vec_C=vec_C(ind_sel);
1119        if ~isempty(ivar_F)
1120           vec_F=vec_F(ind_sel);
1121        end
1122        if ~isempty(ivar_FF_vec)
1123           vec_FF=vec_FF(ind_sel);
1124        end
1125    end
1126   
1127    %get main level color code
1128    [colorlist,col_vec,PlotParamOut.Vectors]=set_col_vec(PlotParam.Vectors,vec_C);
1129   
1130    % take flags into account: add flag colors to the list of colors
1131    sizlist=size(colorlist);
1132    nbcolor=sizlist(1);
1133    if test_black
1134       nbcolor=nbcolor+1;
1135       colorlist(nbcolor,:)=[0 0 0]; %add black to the list of colors
1136       if ~isempty(ivar_FF_vec)
1137            col_vec(vec_F~=1 & vec_F~=0 & vec_FF==0)=nbcolor;
1138       else
1139            col_vec(vec_F~=1 & vec_F~=0)=nbcolor;
1140       end
1141    end
1142    nbcolor=nbcolor+1;
1143    if ~isempty(ivar_FF_vec)
1144        if isfield(PlotParam.Vectors,'CheckHideFalse') && PlotParam.Vectors.CheckHideFalse==1
1145            colorlist(nbcolor,:)=[NaN NaN NaN];% no plot of false vectors
1146        else
1147            colorlist(nbcolor,:)=[1 0 1];% magenta color
1148        end
1149        col_vec(vec_FF~=0)=nbcolor;
1150    end
1151    %plot vectors:
1152    quiresetn(haxes,vec_X,vec_Y,vec_U,vec_V,scale,colorlist,col_vec);   
1153
1154else
1155    hvec=findobj(haxes,'Tag','vel');
1156    if ~isempty(hvec)
1157        delete(hvec);
1158    end
1159    PlotParamOut=rmfield(PlotParamOut,'Vectors');
1160end
1161% nbvar=0;
1162
1163%store the coordinate extrema occupied by the field
1164if ~isempty(Data)
1165    MinX=[];
1166    MaxX=[];
1167    MinY=[];
1168    MaxY=[];
1169    fix_lim=isfield(PlotParam.Axes,'CheckFixLimits') && PlotParam.Axes.CheckFixLimits;
1170    if fix_lim
1171        if isfield(PlotParam.Axes,'MinX')&&isfield(PlotParam.Axes,'MaxX')&&isfield(PlotParam.Axes,'MinY')&&isfield(PlotParam.Axes,'MaxY')
1172            MinX=PlotParam.Axes.MinX;
1173            MaxX=PlotParam.Axes.MaxX;
1174            MinY=PlotParam.Axes.MinY;
1175            MaxY=PlotParam.Axes.MaxY;
1176        end  %else PlotParamOut.MinX =PlotParam.MinX...
1177    else
1178        if test_ima %both background image and vectors coexist, take the wider bound
1179            MinX=min(AX);
1180            MaxX=max(AX);
1181            MinY=min(AY);
1182            MaxY=max(AY);
1183            if test_vec
1184                MinX=min(MinX,min(vec_X));
1185                MaxX=max(MaxX,max(vec_X));
1186                MinY=min(MinY,min(vec_Y));
1187                MaxY=max(MaxY,max(vec_Y));
1188            end
1189        elseif test_vec
1190            MinX=min(vec_X);
1191            MaxX=max(vec_X);
1192            MinY=min(vec_Y);
1193            MaxY=max(vec_Y);
1194        end
1195    end
1196    PlotParamOut.Axes.MinX=MinX;
1197    PlotParamOut.Axes.MaxX=MaxX;
1198    PlotParamOut.Axes.MinY=MinY;
1199    PlotParamOut.Axes.MaxY=MaxY;
1200    if MaxX>MinX
1201        set(haxes,'XLim',[MinX MaxX]);% set x limits of frame in axes coordinates
1202    end
1203    if MaxY>MinY
1204        set(haxes,'YLim',[MinY MaxY]);% set x limits of frame in axes coordinates
1205    end
1206    set(haxes,'YDir','normal')
1207    set(get(haxes,'XLabel'),'String',[XName ' (' x_units ')']);
1208    set(get(haxes,'YLabel'),'String',[YName ' (' y_units ')']);
1209    PlotParamOut.Axes.x_units=x_units;
1210    PlotParamOut.Axes.y_units=y_units;
1211end
1212if isfield(PlotParam,'Coordinates') && isfield(PlotParam.Axes,'CheckFixAspectRatio') && isequal(PlotParam.Axes.CheckFixAspectRatio,1)
1213    set(haxes,'DataAspectRatioMode','manual')
1214    if isfield(PlotParam.Axes,'AspectRatio')
1215        set(haxes,'DataAspectRatio',[PlotParam.Axes.AspectRatio 1 1])
1216    end
1217else
1218    set(haxes,'DataAspectRatioMode','auto')
1219end
1220%-------------------------------------------------------------------
1221% --- function for plotting vectors
1222%INPUT:
1223% haxes: handles of the plotting axes
1224% x,y,u,v: vectors coordinates and vector components to plot, arrays withb the same dimension
1225% scale: scaling factor for vector length representation
1226% colorlist(icolor,:): list of vector colors, dim (nbcolor,3), depending on color #i
1227% col_vec: matlab vector setting the color number #i for each velocity vector
1228function quiresetn(haxes,x,y,u,v,scale,colorlist,col_vec)
1229%-------------------------------------------------------------------
1230%define arrows
1231theta=0.5 ;%angle arrow
1232alpha=0.3 ;%length arrow
1233rot=alpha*[cos(theta) -sin(theta); sin(theta) cos(theta)]';
1234%find the existing lines
1235h=findobj(haxes,'Tag','vel');% search existing lines in the current axes
1236sizh=size(h);
1237set(h,'EraseMode','xor');
1238set(haxes,'NextPlot','replacechildren');
1239
1240%drawnow
1241%create lines (if no lines) or modify them
1242if ~isequal(size(col_vec),size(x))
1243    col_vec=ones(size(x));% case of error in col_vec input
1244end
1245sizlist=size(colorlist);
1246ncolor=sizlist(1);
1247
1248for icolor=1:ncolor
1249    %determine the line positions for each color icolor
1250    ind=find(col_vec==icolor);
1251    xc=x(ind);
1252    yc=y(ind);
1253    uc=u(ind)*scale;
1254    vc=v(ind)*scale;
1255    n=size(xc);
1256    xN=NaN*ones(size(xc));
1257    matx=[xc(:)-uc(:)/2 xc(:)+uc(:)/2 xN(:)]';
1258    matx=reshape(matx,1,3*n(2));
1259    maty=[yc(:)-vc(:)/2 yc(:)+vc(:)/2 xN(:)]';
1260    maty=reshape(maty,1,3*n(2));
1261   
1262    %determine arrow heads
1263    arrowplus=rot*[uc;vc];
1264    arrowmoins=rot'*[uc;vc];
1265    x1=xc+uc/2-arrowplus(1,:);
1266    x2=xc+uc/2;
1267    x3=xc+uc/2-arrowmoins(1,:);
1268    y1=yc+vc/2-arrowplus(2,:);
1269    y2=yc+vc/2;
1270    y3=yc+vc/2-arrowmoins(2,:);
1271    matxar=[x1(:) x2(:) x3(:) xN(:)]';
1272    matxar=reshape(matxar,1,4*n(2));
1273    matyar=[y1(:) y2(:) y3(:) xN(:)]';
1274    matyar=reshape(matyar,1,4*n(2));
1275    %draw the line or modify the existing ones
1276%     tri=reshape(1:3*length(uc),3,[])';   
1277    isn=isnan(colorlist(icolor,:));%test if color NaN
1278    if 2*icolor > sizh(1) %if icolor exceeds the number of existing ones
1279        if ~isn(1) %if the vectors are visible color not nan
1280            if n(2)>0
1281                hold on
1282                line(matx,maty,'Color',colorlist(icolor,:),'Tag','vel');% plot new lines
1283                line(matxar,matyar,'Color',colorlist(icolor,:),'Tag','vel');% plot arrows
1284            end
1285        end
1286    else
1287        if isn(1)
1288            delete(h(2*icolor-1))
1289            delete(h(2*icolor))
1290        else
1291            set(h(2*icolor-1),'Xdata',matx,'Ydata',maty);
1292            set(h(2*icolor-1),'Color',colorlist(icolor,:));
1293            set(h(2*icolor-1),'EraseMode','xor');
1294            set(h(2*icolor),'Xdata',matxar,'Ydata',matyar);
1295            set(h(2*icolor),'Color',colorlist(icolor,:));
1296            set(h(2*icolor),'EraseMode','xor');
1297        end
1298    end
1299end
1300if sizh(1) > 2*ncolor
1301    for icolor=ncolor+1 : sizh(1)/2%delete additional objects
1302        delete(h(2*icolor-1))
1303        delete(h(2*icolor))
1304    end
1305end
1306
1307%-------------------------------------------------------------------
1308% ---- determine tick positions for colorbar
1309function YTick=colbartick(MinA,MaxA)
1310%-------------------------------------------------------------------
1311%determine tick positions with "simple" values between MinA and MaxA
1312YTick=0;%default
1313maxabs=max([abs(MinA) abs(MaxA)]);
1314if maxabs>0
1315ord=10^(floor(log10(maxabs)));%order of magnitude
1316div=1;
1317siz2=1;
1318while siz2<2
1319    values=-10:div:10;
1320    ind=find((ord*values-MaxA)<0 & (ord*values-MinA)>0);%indices of 'values' such that MinA<ord*values<MaxA
1321    siz=size(ind);
1322    if siz(2)<4%if there are less than 4 selected values (4 levels)
1323        values=-9:0.5*div:9;
1324        ind=find((ord*values-MaxA)<0 & (ord*values-MinA)>0);
1325    end
1326    siz2=size(ind,2);
1327    div=div/10;
1328end
1329YTick=ord*values(ind);
1330end
1331
1332% -------------------------------------------------------------------------
1333% --- 'proj_grid': project  fields with unstructured coordinantes on a regular grid
1334function [A,rangx,rangy]=proj_grid(vec_X,vec_Y,vec_A,rgx_in,rgy_in,npxy_in)
1335% -------------------------------------------------------------------------
1336if length(vec_Y)<2
1337    msgbox_uvmat('ERROR','less than 2 points in proj_grid.m');
1338    return;
1339end
1340diffy=diff(vec_Y); %difference dy=vec_Y(i+1)-vec_Y(i)
1341index=find(diffy);% find the indices of vec_Y after wich a change of horizontal line occurs(diffy non zero)
1342if isempty(index); msgbox_uvmat('ERROR','points aligned along abscissa in proj_grid.m'); return; end;%points aligned% A FAIRE: switch to line plot.
1343diff2=diff(diffy(index));% diff2 = fluctuations of the detected vertical grid mesh dy
1344if max(abs(diff2))>0.001*abs(diffy(index(1))) % if max(diff2) is larger than 1/1000 of the first mesh dy
1345    % the data are not regularly spaced and must be interpolated  on a regular grid
1346    if exist('rgx_in','var') & ~isempty (rgx_in) & isnumeric(rgx_in) & length(rgx_in)==2%  positions imposed from input
1347        rangx=rgx_in; % first and last positions
1348        rangy=rgy_in;
1349        dxy(1)=1/(npxy_in(1)-1);%grid mesh in y
1350        dxy(2)=1/(npxy_in(2)-1);%grid mesh in x
1351        dxy(1)=(rangy(2)-rangy(1))/(npxy_in(1)-1);%grid mesh in y
1352        dxy(2)=(rangx(2)-rangx(1))/(npxy_in(2)-1);%grid mesh in x
1353    else % interpolation grid automatically determined
1354        rangx(1)=min(vec_X);
1355        rangx(2)=max(vec_X);
1356        rangy(2)=min(vec_Y);
1357        rangy(1)=max(vec_Y);
1358        dxymod=sqrt((rangx(2)-rangx(1))*(rangy(1)-rangy(2))/length(vec_X));
1359        dxy=[-dxymod/4 dxymod/4];% increase the resolution 4 times
1360    end
1361    xi=[rangx(1):dxy(2):rangx(2)];
1362    yi=[rangy(1):dxy(1):rangy(2)];
1363    A=griddata_uvmat(vec_X,vec_Y,vec_A,xi,yi');
1364    A=reshape(A,length(yi),length(xi));
1365else
1366    x=vec_X(1:index(1));% the set of abscissa (obtained on the first line)
1367    indexend=index(end);% last vector index of line change
1368    ymax=vec_Y(indexend+1);% y coordinate AFTER line change
1369    ymin=vec_Y(index(1));
1370    y=vec_Y(index);
1371    y(length(y)+1)=ymax;
1372    nx=length(x);   %number of grid points in x
1373    ny=length(y);   % number of grid points in y
1374    B=(reshape(vec_A,nx,ny))'; %vec_A reshaped as a rectangular matrix
1375    [X,Y]=meshgrid(x,y);% positions X and Y also reshaped as matrix
1376
1377    %linear interpolation to improve the image resolution and/or adjust
1378    %to prescribed positions
1379    test_interp=1;
1380    if exist('rgx_in','var') & ~isempty (rgx_in) & isnumeric(rgx_in) & length(rgx_in)==2%  positions imposed from input
1381        rangx=rgx_in; % first and last positions
1382        rangy=rgy_in;
1383        npxy=npxy_in;
1384    else       
1385        rangx=[vec_X(1) vec_X(nx)];% first and last position found for x
1386          rangy=[max(ymax,ymin) min(ymax,ymin)];
1387        if max(nx,ny) <= 64 & isequal(npxy_in,'np>256')
1388            npxy=[8*ny 8*nx];% increase the resolution 8 times
1389        elseif max(nx,ny) <= 128 & isequal(npxy_in,'np>256')
1390            npxy=[4*ny 4*nx];% increase the resolution 4 times
1391        elseif max(nx,ny) <= 256 & isequal(npxy_in,'np>256')
1392            npxy=[2*ny 2*nx];% increase the resolution 2 times
1393        else
1394            npxy=[ny nx];
1395            test_interp=0; % no interpolation done
1396        end
1397    end
1398    if test_interp==1%if we interpolate
1399        xi=[rangx(1):(rangx(2)-rangx(1))/(npxy(2)-1):rangx(2)];
1400        yi=[rangy(1):(rangy(2)-rangy(1))/(npxy(1)-1):rangy(2)];
1401        [XI,YI]=meshgrid(xi,yi);
1402        A = interp2(X,Y,B,XI,YI);
1403    else %no interpolation for a resolution higher than 256
1404        A=B;
1405    end
1406end
Note: See TracBrowser for help on using the repository browser.