Сопоставить легенду с осями объектов
Контекст:
У меня есть (программный) графический интерфейс, который содержит несколько axes
объекты внутри некоторых uipanel
структура воспитания. Что-нибудь из этого axes
иметь legend
связанные объекты, некоторые нет.
Я хочу включить кнопку в моем графическом интерфейсе, которая копирует видимый в данный момент график в новую фигуру, включая ее legend
если есть.
Я знаю, как добраться до ручки, видимой в данный момент uipanel
и все axes
объекты внутри него. Я также знаю, как сказать axes
отдельно от legend
s.
Вопрос:
Как я могу соответствовать legend
с axes
?
Например, в одном случае мой графический интерфейс показывает 2 axes
с некоторыми участками, каждый из которых имеет свой legend
, Когда я нажимаю кнопку "Экспорт", я хочу создать 2 новые фигуры, каждая из которых содержит одну axes
с соответствующим legend
,
То, что я в настоящее время могу сделать, это
- положить все в одну фигуру (они перекрываются в этом случае, потому что их позиции в оригинале
uipanel
одинаковы), - поместите каждую ось и каждую легенду в свои соответствующие фигуры,
- положить все оси в одну и все легенды в другую фигуру и
- поместите все оси в их собственную фигуру со всеми легендами в одной панели.
- разделите его на панели, то есть поместите все вспомогательные сюжеты в одну фигуру и каждую группу сюжетов в свою фигуру.
Проблема:
Проблема в том, что у меня нет ручек ни для одного из этих объектов. У меня есть только ручки для uipanel
объекты. Графика внутри панелей построена с помощью другой функции, которая содержит все виды хитрых вещей, но не возвращает маркеры. Также родительская структура упомянутых панелей делает довольно трудным сделать это с помощью таких хитростей, как get(handles.panels{1},'Children')
потому что это будет работать в некоторых, но не во всех случаях.
Я думал о простом экспорте панелей (и у меня действительно есть рабочая версия, которая делает это), но у этого есть несколько проблем, в основном связанных с инструментами рисунка и изменением размера. Я хочу избавиться от панелей, когда использую кнопку "Экспорт".
Фрагмент кода / Пример:
Следующий фрагмент кода создаст пример GUI с доступом ко всем дескрипторам, к которым у меня есть доступ в моем полном GUI. Нажатие на кнопки покажет разные версии, которые я получил, чтобы "работать". То, что я хочу, это одна цифра для каждой оси, включая ее легенду, если она есть. 4-я версия (тот же родитель) подходит близко, но ломается, если встречает subplot
s, 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)