Сопоставить легенду с осями объектов

Контекст:

У меня есть (программный) графический интерфейс, который содержит несколько axes объекты внутри некоторых uipanel структура воспитания. Что-нибудь из этого axes иметь legend связанные объекты, некоторые нет.
Я хочу включить кнопку в моем графическом интерфейсе, которая копирует видимый в данный момент график в новую фигуру, включая ее legend если есть.

Я знаю, как добраться до ручки, видимой в данный момент uipanel и все axes объекты внутри него. Я также знаю, как сказать axes отдельно от legends.

Вопрос:

Как я могу соответствовать legendс axes?

Например, в одном случае мой графический интерфейс показывает 2 axes с некоторыми участками, каждый из которых имеет свой legend, Когда я нажимаю кнопку "Экспорт", я хочу создать 2 новые фигуры, каждая из которых содержит одну axes с соответствующим legend,
То, что я в настоящее время могу сделать, это

  1. положить все в одну фигуру (они перекрываются в этом случае, потому что их позиции в оригинале uipanelодинаковы),
  2. поместите каждую ось и каждую легенду в свои соответствующие фигуры,
  3. положить все оси в одну и все легенды в другую фигуру и
  4. поместите все оси в их собственную фигуру со всеми легендами в одной панели.
  5. разделите его на панели, то есть поместите все вспомогательные сюжеты в одну фигуру и каждую группу сюжетов в свою фигуру.

Проблема:

Проблема в том, что у меня нет ручек ни для одного из этих объектов. У меня есть только ручки для uipanel объекты. Графика внутри панелей построена с помощью другой функции, которая содержит все виды хитрых вещей, но не возвращает маркеры. Также родительская структура упомянутых панелей делает довольно трудным сделать это с помощью таких хитростей, как get(handles.panels{1},'Children') потому что это будет работать в некоторых, но не во всех случаях.
Я думал о простом экспорте панелей (и у меня действительно есть рабочая версия, которая делает это), но у этого есть несколько проблем, в основном связанных с инструментами рисунка и изменением размера. Я хочу избавиться от панелей, когда использую кнопку "Экспорт".

Фрагмент кода / Пример:

Следующий фрагмент кода создаст пример GUI с доступом ко всем дескрипторам, к которым у меня есть доступ в моем полном GUI. Нажатие на кнопки покажет разные версии, которые я получил, чтобы "работать". То, что я хочу, это одна цифра для каждой оси, включая ее легенду, если она есть. 4-я версия (тот же родитель) подходит близко, но ломается, если встречает subplots, 5-я версия (по панелям) просто помещает целые группы подзаговоров в одно окно (в этом случае, по крайней мере, они не перекрываются). Скопируйте код в новый .mфайл, чтобы попробовать это.

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

3 ответа

На рисунке графические объекты организованы иерархически и могут обрабатываться индивидуально. Например, оси являются дочерними элементами фигуры, сюжет является дочерними элементами осей, а легенды строятся как оси.

В следующем примере показаны две линии (красная и синяя, с легендами), затем смешаны графики и легенды, используя 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

Не проверено с GUI, хотя.

Я думаю, что более простое решение - сохранить оси фигуры, которую вы собираетесь сохранить, в виде фигового файла.

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');

Я использую Matlab R2012a, в качестве альтернативы в R2013a или b функция сохранить рис сейчас savefig,

Как только вы получили дескриптор осей, вы можете найти соответствующий дескриптор легенды, используя

legend_handle = legend(axes_handle)

Другие вопросы по тегам