Home > RAVEN > drawPathway.m

drawPathway

PURPOSE ^

drawPathway

SYNOPSIS ^

function drawPathway(pathway, handle, cutOff, defaultColor)

DESCRIPTION ^

 drawPathway
    Draws a metabolic network to a figure.

   pathway         pathway structure representing the pathway to be drawn
   handle          handle to a figure (opt)
   cutOff          the fluxes are only printed if the absolute value of 
                   at least one of the fluxes is above the cutoff value
                   (opt, default 0)
   defaultColor    color in Matlab format to be used as the background
                   color for enzymes if no color is specified in the
                   pathway structure (opt, default [1 1 1])

   NOTE:   At the moment all text sizes and some positions are hard coded.
           This means that this code is not appliable for any map

   Usage: drawPathway(pathway, handle, cutOff, defaultColor)

   Rasmus Agren, 2012-03-26

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function drawPathway(pathway, handle, cutOff, defaultColor)
0002 % drawPathway
0003 %    Draws a metabolic network to a figure.
0004 %
0005 %   pathway         pathway structure representing the pathway to be drawn
0006 %   handle          handle to a figure (opt)
0007 %   cutOff          the fluxes are only printed if the absolute value of
0008 %                   at least one of the fluxes is above the cutoff value
0009 %                   (opt, default 0)
0010 %   defaultColor    color in Matlab format to be used as the background
0011 %                   color for enzymes if no color is specified in the
0012 %                   pathway structure (opt, default [1 1 1])
0013 %
0014 %   NOTE:   At the moment all text sizes and some positions are hard coded.
0015 %           This means that this code is not appliable for any map
0016 %
0017 %   Usage: drawPathway(pathway, handle, cutOff, defaultColor)
0018 %
0019 %   Rasmus Agren, 2012-03-26
0020 %
0021 
0022 if nargin<4
0023     defaultColor=[1 1 1];
0024 end
0025 if nargin<3
0026     cutOff=0;
0027 end
0028 if nargin<2
0029     handle=figure();
0030 else
0031     figure(handle);
0032 end
0033 
0034 %Will contain all metabolite info and where to print them
0035 metText={};
0036 metX=[];
0037 metY=[];
0038 metRec=[];
0039 
0040 %Same for reaction text (names, fluxes and maybe other)
0041 rxnText={};
0042 rxnX=[];
0043 rxnY=[];
0044 rxnLinesX=[];
0045 rxnLinesY=[];
0046 rxnRec=[];
0047 rxnFace=[];
0048 rxnEdge=[];
0049 rxnArrows=[];
0050 rxnArrowsColor=[];
0051 
0052 %Expression boxes
0053 expRec=[];
0054 expFace=[];
0055 
0056 %Lines to enzymes
0057 enzLinesX=[];
0058 enzLinesY=[];
0059 
0060 %Same for compartments
0061 compText={};
0062 compX=[];
0063 compY=[];
0064 compRec=[];
0065 
0066 %Check if it should plot expression data
0067 if isfield(pathway.listOfSpecies(1),'orfs')
0068     drawExpression=true;
0069 else
0070     drawExpression=false;
0071 end
0072 
0073 %Get the dimensions of the network
0074 dimension=getPathwayDimensions(pathway);
0075 
0076 %Specify the properties of the figure
0077 set(gcf, 'PaperOrientation', 'landscape');
0078 set(gcf, 'Color', [1 1 1]);
0079 xmargin=0.83;
0080 ymargin=1.32;
0081 set(gcf, 'PaperPosition', [xmargin ymargin 29.67743169791-2*xmargin 20.98404194812-2*ymargin]);
0082 set(gcf, 'Renderer', 'painters');
0083 set(gcf, 'Position', [10 10 1000 700]);
0084 
0085 %The height has to be at least the height of the information panel
0086 %(approximately 3000)
0087 height=dimension(2)+dimension(4)+200;
0088 height=max(height,3000);
0089 
0090 axes('ytick',[],'ydir','reverse','xtick',[],'ycolor',[1 1 1], 'xcolor',...
0091     [1 1 1],'position',[0 0 1 1], 'xLim',[dimension(1)-40 dimension(1)+dimension(3)+800],...
0092     'yLim', [dimension(2)-200 height]);
0093 daspect([1,1,1]);
0094 
0095 %Loops through the compartments.
0096 for i=1:length(pathway.listOfCompartments)
0097     position=[pathway.listOfCompartments(1,i).x pathway.listOfCompartments(1,i).y...
0098         pathway.listOfCompartments(1,i).w pathway.listOfCompartments(1,i).h];
0099     compRec=[compRec;position];
0100     compText=[compText;upper(pathway.listOfCompartments(i).name)];
0101     compX=[compX;position(1)+0.5*position(3)];
0102     compY=[compY;position(2)+position(4)-70];
0103 end
0104 
0105 %Get positions of lines
0106 for i=1:length(pathway.listOfReactions)
0107     for j=1:length(pathway.listOfReactions(i).componentList)
0108         %The line is always drawn from the middle to the component
0109         middle=pathway.listOfReactions(i).middlePoint;
0110         x(1)=middle(1);
0111         y(1)=middle(2);
0112         x(2)=pathway.listOfReactions(i).componentList(j).anchor(1);
0113         y(2)=pathway.listOfReactions(i).componentList(j).anchor(2);
0114         
0115         %Check to see if a line or an arrow should be drawn
0116         if strcmpi(pathway.listOfReactions(i).componentList(j).toArrow,'true')
0117             rxnArrows=[rxnArrows;x(1) y(1) x(2) y(2)];
0118             
0119             %Draw a red arrow if it's a base product
0120             if strcmpi(pathway.listOfReactions(i).componentList(j).baseProduct,'true')
0121                 rxnArrowsColor=[rxnArrowsColor;1 0 0];
0122             else
0123                 rxnArrowsColor=[rxnArrowsColor;0 0 0];
0124             end
0125         else
0126             %If the component is an enzyme then a different line should be
0127             %used
0128             if strcmpi(pathway.listOfReactions(i).componentList(j).type,'ENZYME')
0129                 enzLinesX=[enzLinesX;x(1) x(2)];
0130                 enzLinesY=[enzLinesY;y(1) y(2)];
0131             else
0132                 rxnLinesX=[rxnLinesX;x(1) x(2)];
0133                 rxnLinesY=[rxnLinesY;y(1) y(2)];
0134             end
0135         end
0136     end
0137 end
0138 
0139 %Loops through the species
0140 for i=1:length(pathway.listOfSpecies)
0141     %Species should be represented with ellipses and enzymes with
0142     %rectangles
0143     position=[pathway.listOfSpecies(i).x pathway.listOfSpecies(i).y...
0144             pathway.listOfSpecies(i).w pathway.listOfSpecies(i).h];
0145     if strcmpi(pathway.listOfSpecies(i).type, 'SIMPLE_MOLECULE')
0146         metRec=[metRec;position];
0147         metText=[metText;pathway.listOfSpecies(i).name];
0148         metX=[metX;position(1)+0.3*position(3)];
0149         metY=[metY;position(2)+0.5*position(4)];
0150     end
0151     if strcmpi(pathway.listOfSpecies(i).type, 'PROTEIN')
0152         %The color of the enzyme can be specified in the pathway object.
0153         %The default color is used if there is no 'color' field present.
0154         %If neither of the fluxes are above the cutoff value, then use the
0155         %default color
0156         faceColor=defaultColor;
0157         if isfield(pathway.listOfSpecies(i),'color')
0158             if any(pathway.listOfSpecies(i).color)      
0159                 %Check that the fluxes are specified
0160                 if isfield(pathway.listOfSpecies(i),'flux') && isfield(pathway.listOfSpecies(i),'referenceFlux')
0161                     %Check that the value of one of the fluxes is above the cutoff value
0162                     if abs(pathway.listOfSpecies(i).referenceFlux)>=cutOff || abs(pathway.listOfSpecies(i).flux)>=cutOff 
0163                         faceColor=pathway.listOfSpecies(i).color;
0164                     end
0165                 end
0166             end
0167         end
0168         
0169         %If the reaction is associated with a sign change and either of the
0170         %fluxes are larger than the cutoff value, then use a different frame
0171         edgeColor=[0 0 0];
0172         if isfield(pathway.listOfSpecies(i),'signChange')
0173             if any(pathway.listOfSpecies(i).signChange)
0174                 if (pathway.listOfSpecies(i).signChange==true) && (abs(pathway.listOfSpecies(i).referenceFlux)>=cutOff || abs(pathway.listOfSpecies(i).flux)>=cutOff)
0175                     edgeColor=[1 0.6 0.2];
0176                 end
0177             end
0178         end
0179         
0180         rxnFace=[rxnFace;faceColor];
0181         rxnEdge=[rxnEdge;edgeColor];
0182         
0183         %Draw smaller boxes if expression data should also be printed
0184         if drawExpression==true
0185             rxnRec=[rxnRec;position-[0 0 40 0]];
0186             
0187             %Draw rectangles representing each gene. Max 8 circles are used.
0188             %Their width is hardcoded and so is the width of the area where
0189             %they are printed (40)
0190             if any(pathway.listOfSpecies(i).expA)
0191                 %Calculate the position of the dots. 4 in each column.
0192                 firstFourX=pathway.listOfSpecies(i).x+pathway.listOfSpecies(i).w-34;
0193                 fourY=pathway.listOfSpecies(i).y:pathway.listOfSpecies(i).h/4:pathway.listOfSpecies(i).y+pathway.listOfSpecies(i).h;
0194                 
0195                 nExp=numel(pathway.listOfSpecies(i).expA);
0196                 
0197                 %One log10-fold change is total up or down
0198                 colorCodes=getColorCodes(pathway.listOfSpecies(i).expA, pathway.listOfSpecies(i).expB);
0199 
0200                 %Plot the circles
0201                 for j=1:min(nExp,4)
0202                     expRec=[expRec;firstFourX fourY(j) 16 pathway.listOfSpecies(i).h/4];
0203                     expFace=[expFace;colorCodes{j}];
0204                 end
0205                 
0206                 %If a second row is needed
0207                 if nExp>4
0208                     secondFourX=pathway.listOfSpecies(i).x+pathway.listOfSpecies(i).w-16;
0209                     for j=5:min(nExp,8)
0210                         expRec=[expRec;secondFourX fourY(j-4) 16 pathway.listOfSpecies(i).h/4];
0211                         expFace=[expFace;colorCodes{j}];
0212                     end
0213                 end
0214             end
0215         else
0216             rxnRec=[rxnRec;position];
0217         end
0218         
0219         %If no fluxes are specified then should only the name be printed.
0220         %Flux values should only be printed if at least one of the fluxes
0221         %is above the cutoff value
0222         textToPrint={};
0223         
0224         %NOTE:  This is done since I know that I have names including '_' which is a reserved
0225         %       character in LaTeX. This should be done more systematically
0226         
0227         %NOTE:  The notation used means that only flux values with with less than
0228         %       nine characters can be used
0229         
0230         textToPrint{1,1}=strrep(pathway.listOfSpecies(i).name,'_','\_');
0231         
0232         %Check that the fluxes are specified
0233         %NOTE: Should you only print if there are two fluxes?
0234         if isfield(pathway.listOfSpecies(i),'flux') && isfield(pathway.listOfSpecies(i),'referenceFlux')
0235             %Check that the value of one of the fluxes is above the cutoff value
0236             if ~isempty(pathway.listOfSpecies(i).flux) && ~isempty(pathway.listOfSpecies(i).referenceFlux)
0237                 if abs(pathway.listOfSpecies(i).referenceFlux)>=cutOff || abs(pathway.listOfSpecies(i).flux)>=cutOff 
0238                     textToPrint{2,1}=num2str(pathway.listOfSpecies(i).flux,'%0.4g');
0239                     textToPrint{3,1}=num2str(pathway.listOfSpecies(i).referenceFlux,'%0.4g');
0240                 end
0241             end
0242         end
0243 
0244         xPos=ones(numel(textToPrint),1)*(position(1)+3);
0245         distance=position(4)/(numel(textToPrint)+1);
0246         yPos=position(2)+distance:distance:(position(2)+position(4)-distance);
0247         
0248         rxnText=[rxnText;textToPrint];
0249         rxnX=[rxnX;xPos];
0250         rxnY=[rxnY;yPos'];
0251     end
0252 end
0253 
0254 %*** Print everything ***
0255 
0256 %Compartment rectangles
0257 for i=1:size(compRec,1)
0258     rectangle('edgecolor',[1 0.8 0.2], 'facecolor', [1 0.91 0.55], 'linewidth', 2, 'curvature', [0.05 0.05],...
0259         'position',compRec(i,:));
0260     rectangle('edgecolor',[1 0.8 0.2], 'facecolor', [1 1 1], 'linewidth', 1, 'curvature', [0.05 0.05],...
0261         'position',compRec(i,:)+[12 12 -24 -24]);
0262 end
0263 
0264 %Reaction lines
0265 line(rxnLinesX',rxnLinesY','linewidth',0.1,'color',[0 0 0]);
0266 
0267 %Arrow lines
0268 hold on;
0269 for i=1:size(rxnArrows,1)
0270     plotArrow(rxnArrows(i,1),rxnArrows(i,2),rxnArrows(i,3),rxnArrows(i,4),'linewidth',0.1,'edgecolor',rxnArrowsColor(i,:),'facecolor',rxnArrowsColor(i,:));
0271 end
0272 hold off;
0273 
0274 %Enzyme lines
0275 line(enzLinesX',enzLinesY','marker','o','markeredgecolor',[0 0 0],'markersize',0.5,...
0276     'markerfacecolor',[1 0.969 0.922],'linewidth',0.1,'color',[0 0 0]);
0277 
0278 %Metabolite rectangles
0279 for i=1:size(metRec,1)
0280     rectangle('edgecolor', [0 0 0], 'facecolor', [1 1 0.78], 'curvature', [0.8 0.8],...
0281                 'position',metRec(i,:),'linewidth',0.1);
0282 end
0283 
0284 %Reaction rectangles
0285 for i=1:size(rxnRec,1)
0286     rectangle('edgecolor', rxnEdge(i,:), 'facecolor', rxnFace(i,:), 'linewidth',0.1,...
0287         'curvature', [0.1 0.1], 'position',rxnRec(i,:));  
0288 end
0289 
0290 %Expression rectangles
0291 for i=1:size(expRec,1)
0292     rectangle('facecolor', expFace(i,:), 'linewidth',0.1, 'curvature', [0.1 0.1],...
0293         'position',expRec(i,:));
0294 end
0295 
0296 %Metabolite text
0297 %Temporary thing to get it right for small networks as well. Should be
0298 %calculated better!
0299 if dimension(3)<5000
0300     textSize=3;
0301 else
0302     textSize=0.5;
0303 end
0304 
0305 text(metX,metY,metText,'fontname','Small Fonts','fontsize',textSize,'interpreter','tex',...
0306     'HorizontalAlignment','center','verticalalignment','middle');
0307 
0308 %Reaction text
0309 text(rxnX,rxnY,rxnText,'fontname','Small Fonts','fontsize',textSize,'interpreter','tex',...
0310     'verticalalignment','middle','HorizontalAlignment','left');
0311 
0312 %Compartment text. The text is centered and at the bottom of the compartment
0313 text(compX, compY,compText,'fontname','Small Fonts','fontsize',7,'interpreter','none',...
0314     'HorizontalAlignment','center','verticalalignment','middle');      
0315 end
0316 
0317 function handles = plotArrow( x1,y1,x2,y2,varargin )
0318 %
0319 % plotArrow - plots an arrow to the current plot
0320 %
0321 % format:   handles = plotArrow( x1,y1,x2,y2 [,options...] )
0322 %
0323 % input:    x1,y1   - starting point
0324 %           x2,y2   - end point
0325 %           options - come as pairs of "property","value" as defined for "line" and "patch"
0326 %                     controls, see matlab help for listing of these properties.
0327 %                     note that not all properties where added, one might add them at the end of this file.
0328 %
0329 %                     additional options are:
0330 %                     'headwidth':  relative to complete arrow size, default value is 0.07
0331 %                     'headheight': relative to complete arrow size, default value is 0.15
0332 %                     (encoded are maximal values if pixels, for the case that the arrow is very long)
0333 %
0334 % output:   handles - handles of the graphical elements building the arrow
0335 %
0336 % Example:  plotArrow( -1,-1,15,12,'linewidth',2,'color',[0.5 0.5 0.5],'facecolor',[0.5 0.5 0.5] );
0337 %           plotArrow( 0,0,5,4,'linewidth',2,'headwidth',0.25,'headheight',0.33 );
0338 %           plotArrow;   % will launch demo
0339 
0340 % =============================================
0341 % constants (can be edited)
0342 % =============================================
0343 %NOTE: These should be 100 times smaller
0344 alpha       = 15;   % head length
0345 beta        = 7;   % head width
0346 max_length  = 11;
0347 max_width   = 7;
0348 
0349 % =============================================
0350 % check if head properties are given
0351 % =============================================
0352 % if ratio is always fixed, this section can be removed!
0353 if ~isempty( varargin )
0354     for c = 1:floor(length(varargin)/2)
0355         switch lower(varargin{c*2-1})
0356             % head properties - do nothing, since handled above already
0357         case 'headheight',alpha = max( min( varargin{c*2},1 ),0.01 );
0358         case 'headwidth', beta = max( min( varargin{c*2},1 ),0.01 );
0359         end
0360     end
0361 end
0362 
0363 % =============================================
0364 % calculate the arrow head coordinates
0365 % =============================================
0366 den         = x2 - x1 + eps;                                % make sure no devision by zero occurs
0367 teta        = atan( (y2-y1)/den ) + pi*(x2<x1) - pi/2;      % angle of arrow
0368 cs          = cos(teta);                                    % rotation matrix
0369 ss          = sin(teta);
0370 R           = [cs -ss;ss cs];
0371 line_length = sqrt( (y2-y1)^2 + (x2-x1)^2 );                % sizes
0372 head_length = min( line_length*alpha,max_length );
0373 head_width  = min( line_length*beta,max_length );
0374 x0          = x2*cs + y2*ss;                                % build head coordinats
0375 y0          = -x2*ss + y2*cs;
0376 coords      = R*[x0 x0+head_width/2 x0-head_width/2; y0 y0-head_length y0-head_length];
0377 
0378 % =============================================
0379 % plot arrow  (= line + patch of a triangle)
0380 % =============================================
0381 h1          = plot( [x1,x2],[y1,y2],'k' );
0382 h2          = patch( coords(1,:),coords(2,:),[0 0 0] );
0383     
0384 % =============================================
0385 % return handles
0386 % =============================================
0387 handles = [h1 h2];
0388 
0389 % =============================================
0390 % check if styling is required
0391 % =============================================
0392 % if no styling, this section can be removed!
0393 if ~isempty( varargin )
0394     for c = 1:floor(length(varargin)/2)
0395         switch lower(varargin{c*2-1})
0396 
0397          % only patch properties
0398         case 'edgecolor',   set( h2,'EdgeColor',varargin{c*2} );
0399         case 'facecolor',   set( h2,'FaceColor',varargin{c*2} );
0400         case 'facelighting',set( h2,'FaceLighting',varargin{c*2} );
0401         case 'edgelighting',set( h2,'EdgeLighting',varargin{c*2} );
0402 
0403         % only line properties
0404         case 'color'    , set( h1,'Color',varargin{c*2} );
0405 
0406         % shared properties
0407         case 'linestyle', set( handles,'LineStyle',varargin{c*2} );
0408         case 'linewidth', set( handles,'LineWidth',varargin{c*2} );
0409         case 'parent',    set( handles,'parent',varargin{c*2} );
0410 
0411         % head properties - do nothing, since handled above already
0412         case 'headwidth',;
0413         case 'headheight',;
0414 
0415         end
0416     end
0417 end
0418 end

Generated on Mon 06-Jan-2014 14:58:12 by m2html © 2005