Match legend to axes objects

Context:

I have a (programmatic) GUI which contains several axes objects inside some uipanel parenting structure. Some of these axes have legend objects associated, some don't.
I want to include a button in my GUI which copies the currently visible plot into a new figure including its legend if it has one.

I know how to get the handles to the currently visible uipanel and all axes objects inside it. I also know how to tell the axes apart from the legend s.

Question:

How can I match the legend s to the axes ?

For example, in one case my GUI shows 2 axes with some plots, each of which has its own legend . When I click the 'export' button, I want 2 new figures to be created, each containing one axes with its corresponding legend .
What I'm currently able to do is

  • put everything in one figure (they overlap in that case because their positions in the original uipanel s are the same),
  • put each axes and each legend into their own respective figures,
  • put all axes in one and all legends in another figure and
  • put all axes in their own figure with all legends within the same panel.
  • split it up by panel, that is, put all subplots into the same figure and each group of plots in their own figure.
  • Problem:

    The problem is, I don't have the handles to either of those objects. I only have the handles to the uipanel objects. The graphics inside the panels are built by another function which contains all sorts of tricky stuff, but doesn't return handles. Also the parenting structure of said panels makes it rather hard to do this with tricks like get(handles.panels{1},'Children') because it will work in some, but not all cases.
    I thought about simply exporting the panels (and have actually a working version which does this), but this has several problems, mainly related to figure tools and resizing. I want to get rid of the panels when I use the "Export" button.

    Code Snippet / Example:

    The following code snippet will create an example GUI with access to all handles I have access to in my complete GUI. Clicking the buttons will show the different versions I got to "work". What I want is one figure for each axes including its legend, if it has one. the 4th version (same parent) comes close, but breaks if it encounters subplot s, the 5th version (by panel) simply puts entire subplot groups into one window (in which case, at least, they don't overlap). Copy the code into a new .m file to try it.

    function test
        figure(1)
        clf
        t=(0:0.1:10)'; %'// dummy comment
        p2 = uipanel('Visible','off','Position',[0 0 1 1]);
        p1 = uipanel('position',[0 0 1 1]);
        p11 = uipanel('Parent',p1,'Position',[0 0 0.5 0.9]);
        p12 = uipanel('Parent',p1,'Position',[0.5 0 0.5 0.9]);
        uicontrol('Style','push','String','all in one','Units','norm',...
            'Position',[0.05 0.91 0.14 0.06],'Callback',@export1);
        uicontrol('Style','push','String','all in own','Units','norm',...
            'Position',[0.24 0.91 0.14 0.06],'Callback',@export2);
        uicontrol('Style','push','String','by type','Units','norm',...
            'Position',[0.43 0.91 0.14 0.06],'Callback',@export3);
        uicontrol('Style','push','String','same parent','Units','norm',...
            'Position',[0.62 0.91 0.14 0.06],'Callback',@export4);
        uicontrol('Style','push','String','same panel','Units','norm',...
            'Position',[0.81 0.91 0.14 0.06],'Callback',@export5);
        subplot(1,1,1,'Parent',p11)
        plot(t,[sin(t) cos(t)])
        legend('Sine','Cosine')
        subplot(2,1,1,'Parent',p12)
        plot(t,[polyval([0.05 -1 2],t) exp(-t) abs(t-3)])
        subplot(2,1,2,'Parent',p12)
        plot(t,erf(t))
        legend('Error function')
    
        function export1(~,~)
            current = findobj('Type','uipanel','Parent',1,'Visible','on');
            visible_axes = findobj(current,'Type','axes');
            copyobj(visible_axes,figure);
        end
    
        function export2(~,~)
            current = findobj('Type','uipanel','Parent',1,'Visible','on');
            visible_axes = findobj(current,'Type','axes');
            for i=1:length(visible_axes)
                copyobj(visible_axes(i),figure);
            end
        end
    
        function export3(~,~)
            current = findobj('Type','uipanel','Parent',1,'Visible','on');
            visible_axes = findobj(current,'Type','axes','Tag','');
            visible_legends = findobj(current,'Tag','legend');
            copyobj(visible_axes,figure);
            copyobj(visible_legends,figure);
        end
    
        function export4(~,~)
            current = findobj('Type','uipanel','Parent',1,'Visible','on');
            visible_axes = findobj(current,'Type','axes','Tag','');
            visible_legends = findobj(current,'Tag','legend');
            for i=1:length(visible_axes)
                par = get(visible_axes(i),'Parent');
                same = findobj(visible_legends,'Parent',par);
                h=figure;
                copyobj(visible_axes(i),h)
                copyobj(same,h)
            end
        end
    
        function export5(~,~)
            current = findobj('Type','uipanel','Parent',1,'Visible','on');
            visible_axes = findobj(current,'Type','axes');
            parents = cell2mat(get(visible_axes,'Parent'));
            uparents = unique(parents);
            for i=1:length(uparents)
                copyobj(visible_axes(parents==uparents(i)),figure)
            end
        end
    end
    

    In a figure, graphical objects are organized hierarchically and can all be handled individually. For instance, axes is a child of a figure, plot is a child of an axes, and legends are build as axes.

    The following example plots 2 lines (red and blue, with legends), then mixes plots and legends using copyobj .

    figure;
    subplot(1,2,1)
    hp1 = plot(1:10,'r')
    hl1 = legend('red')
    
    subplot(1,2,2)
    hp2 = plot(1:10,'b')
    hl2 = legend('blue')
    
    hf = figure;
    hax = axes;
    copyobj(hp1, hax);    %copy plot to axes
    copyobj(hl2, hf);     %copy legend to figure
    

    Not tested with a GUI though.


    I think the simpler solution is to save the axes of the figure you're about to save as a fig file.

    h = figure(1);
    
    x = linspace(1,100);
    y = 2*x;
    
    ax = findall(h,'type','axes');
    plot(x,y);
    
    save('youraxes', 'ax');
    hgsave(h, 'yourfig.fig');
    

    I'm using Matlab R2012a, alternatively in R2013a or b the function to save the fig is now savefig .


    一旦你获得了轴柄,你可以找到相应的图例柄

    legend_handle = legend(axes_handle)

    链接地址: http://www.djcxy.com/p/18990.html

    上一篇: 渲染脚本渲染比Android上的OpenGL渲染慢得多

    下一篇: 将图例与轴对象匹配