
One legend for a group of subtightplots
    5 Ansichten (letzte 30 Tage)
  
       Ältere Kommentare anzeigen
    
    Sim
      
 am 23 Apr. 2024
  
    
    
    
    
    Kommentiert: Adam Danz
    
      
 am 25 Apr. 2024
            In the following plot, formed by 4 subtightplots, how can I have just one (outside) legend for the left plots, and just one right (outside) legend for the right plots?
addpath('/.../subtightplot');
subplot = @(m,n,p) subtightplot (m, n, p, [0.03 0], [0.04 0.03], [0.06 0.06]);
figure('position',[700 100 1200 1200],'Color',[1 1 1]);
hold on
for i = 1 : 4
    subplot(2,2,i); 
    if i == 1 || i == 3 %%% left plots
        hold on
            t = 0:1:10;
            plot(t,20.*cos(t),'^--','LineWidth',1,'Color','b')
            plot(1:10,(1:10).^2,'^--','LineWidth',1,'Color','k')
            plot(1:10,(1:10).^2.3,'^--','LineWidth',1,'Color','g')
        hold off
    else                %%% right plots
        hold on
            plot(1:10,randi([-50,50],10,1),'o-','LineWidth',1,'Color','r')
            plot(1:10,randi([-50,50],10,1),'o-','LineWidth',1,'Color','m')
            plot(1:10,randi([-50,50],10,1),'o-','LineWidth',1,'Color','y')
        hold off
    end
    legend('Box','off');
end
hold off

This is the my desired result:

0 Kommentare
Akzeptierte Antwort
  Adam Danz
    
      
 am 23 Apr. 2024
        
      Bearbeitet: Adam Danz
    
      
 am 23 Apr. 2024
  
      That FEX function subtightplot is very useful but since R2019b you can use tiledlayout instead and since R2020b, tiledlayout supports global legend placement.
Here's a demo. 
fig = figure(); 
tcl = tiledlayout(fig,2,2,...
    'TileSpacing','none',...        % spacing between tiles
    'Padding','compact', ...        % spacing round perimeter
    'TileIndexing', 'columnmajor'); % index by columns
ax1 = nexttile(tcl);                % generate the next tile/axes
hLeft = plot(rand(20,3)+[0 2 4]);           % return line handles
ax1.ColorOrder = [0 0 1; 0 0 0; 0 1 0];
ax1.LineStyleOrder = '--^';
ax2 = nexttile(tcl);
plot(rand(20,3)+[0 2 4]);
ax2.ColorOrder = ax1.ColorOrder;
ax2.LineStyleOrder = ax1.LineStyleOrder;
ax3 = nexttile(tcl); 
hRight = plot(rand(20,3).*[1 1.2 1.5]);
ax3.ColorOrder = spring(3);
ax3.LineStyleOrder = '-o';
ax4 = nexttile(tcl);
plot(rand(20,3).*[1 1.2 1.5]);
ax4.ColorOrder = ax3.ColorOrder;
ax4.LineStyleOrder = ax3.LineStyleOrder;
linkaxes([ax1,ax2])                 % link left axes limits
linkaxes([ax3,ax4])                 % link right axes limits
legLeft = legend(hLeft);            % create left legend
legLeft.Layout.Tile = 'west';       % put legend in left margin
legRight = legend(hRight);          % create right legend
legRight.Layout.Tile = 'east';      % put legend in right margin

5 Kommentare
  Adam Danz
    
      
 am 23 Apr. 2024
				
      Bearbeitet: Adam Danz
    
      
 am 23 Apr. 2024
  
			Well done!  It looks like the data in the upper two axes are identical to the data in the lower two axes.  If that's the case, just plot the data on the upper axes and use copyobj to copy the graphics objects to the lower axes. 
I refactored your code to demonstrate this suggestion but I did not test it.  Please take some time to understand what each line is doing. 
% It looks like the data in the upper two axes are identical to the data in the lower two axes.  If that's the case, just plot the data on the upper axes and use copyobj to copy the graphics objects to the lower axes.
fig = figure('position',[700 100 1200 1200],'Color',[1 1 1]);
tcl = tiledlayout(fig,2,2,...
    'TileSpacing','none',...
    'Padding','compact', ...
    'TileIndexing', 'columnmajor');
ax = gobjects(1,4);
% Plot upper left axes
ax(1) = nexttile(tcl,1);
hold on
t = 0:1:10;
hLeft(1) = plot(t,20.*cos(t),'LineWidth',1,'Color','b');
hLeft(2) = plot(1:10,(1:10).^2,'LineWidth',1,'Color','k');
hLeft(3) = plot(1:10,(1:10).^2.3,'LineWidth',1,'Color','g');
hold off
% Plot upper right axes
ax(3) = nexttile(tcl,3);
hold on
hRight(1) = plot(1:10,randi([-50,50],10,1),'LineWidth',1,'Color','r');
hRight(2) = plot(1:10,randi([-50,50],10,1),'LineWidth',1,'Color','m');
hRight(3) = plot(1:10,randi([-50,50],10,1),'LineWidth',1,'Color','y');
hold off
% Copy content from upper left axes to lower left axes
ax(2) = nexttile(tcl,2);
copyobj(ax(1).Children,ax(2))
% Copy content from upper right axes to lower right axes
ax(4) = nexttile(tcl,4);
copyobj(ax(3).Children,ax(4))
% set axes properties for left axes
set(ax([1,2]), 'LineStyleOrder', '--^')
% set axes properties for right axes
set(ax([3,4]), 'LineStyleOrder', 'o-')
linkaxes(ax(1:2))             % link left axes limits
linkaxes(ax(3:4))             % link right axes limits
legLeft = legend(hLeft);            % create left legend
legLeft.Layout.Tile = 'west';       % put legend in left margin
legRight = legend(hRight);          % create right legend
legRight.Layout.Tile = 'east';      % put legend in right margin
Weitere Antworten (1)
  Sim
      
 am 25 Apr. 2024
        
      Bearbeitet: Sim
      
 am 25 Apr. 2024
  
      
      1 Kommentar
  Adam Danz
    
      
 am 25 Apr. 2024
				Great comparison, @Sim!  Thanks for sharing.  You're right that  subtightplot has greater flexibiliy around spacing.  In tiledlayout you can set the TileSpacing and Padding properties to a discrete list of enumerators but subtightplot lets you specify the gap and margins numerically.  
Siehe auch
Kategorien
				Mehr zu Axes Appearance finden Sie in Help Center und File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!




