Matlab: Как получить все ручки осей в ручке фигуры?

30

Как получить все оси в ручке рисунка?

С учетом фигурного дескриптора hf я обнаружил, что get(hf, 'children') может возвращать дескрипторы всех осей. Тем не менее, Справка Matlab подсказывает, что она может возвращать больше, чем просто ручки осей:

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

Есть ли способ получить только ручку оси в фигурной ручке? Или как мне узнать, является ли дескриптор, возвращаемый get(hf, 'children') дескриптором топора?

Спасибо!

Теги:
figure
axes

4 ответа

30
Лучший ответ

Используйте FINDALL:

allAxesInFigure = findall(figureHandle,'type','axes');

Если вы хотите получить все оси в любом месте Matlab, вы можете сделать следующее:

allAxes = findall(0,'type','axes');

ИЗМЕНИТЬ

Чтобы ответить на вторую часть вашего вопроса: вы можете проверить, является ли список ручек осями, получив свойства type:

isAxes = strcmp('axes',get(listOfHandles,'type'));

isAxes будет истинным для каждого дескриптора типа axes.

EDIT2

Чтобы выбрать только оси, которые не являются легендами, вам необходимо очистить список осей (ax), удалив все дескрипторы, чей тег не является 'legend' или 'Colorbar':

axNoLegendsOrColorbars= ax(~ismember(get(ax,'Tag'),{'legend','Colobar'}))
  • 0
    Это недоиспользуемая функция обхода кашля .
  • 0
    Простой findall не сработает, если у вашей фигуры есть легенды / цветовые полосы / и т.д .: это «объекты пользовательского интерфейса», упомянутые в бите документации, которую вы процитировали, и f∈dallfindall также вернет дескрипторы для них. Вам нужно будет объединить f∈dallfindall с strcmpstrcmp, проверяющим не тип, а класс, через strcmp (class (hand≤ (потенциальная сторона))) strcmp (класс (дескриптор (потенциальная ручка)))
Показать ещё 5 комментариев
2

Решение по @tm1 отлично. Mine немного сложнее (если вы в порядке с функциональным программированием):

% initialize `fig` somehow, i.e., "fig=gcf()" for the current figure or
% "fig=get(0,'children')" for all open figures; can be vector or scalar.

ax = findall(fig, 'type', 'axes');
ax = ax(arrayfun(@(i) strcmp(class(handle(i)), 'axes'), ax));

ax будет содержать только оси графика. Это работает, потому что class объекта легенды или colorbar отличается от axes.

Изменить @Jonas указывает на потенциальное улучшение фильтрации результатов findall, поскольку, по крайней мере, у легенд и цветных панелей есть непустые свойства Tag: замените последнюю строку в над фрагментом кода с

ax = ax(strcmp('', get(ax, 'Tag')))

Оба эти метода являются kludgy и могут ломаться в будущем (сравнение с ggplot2 или Bokeh может быть интересно).

  • 0
    mlint (анализатор исходного кода, который редактор Matlab использует для вставки в ваш код уродливых подчеркиваний) тупо говорит, что я должен использовать isa вместо strcmp(class(...), '...') но, конечно, это не «т работать здесь , потому что объекты легенды / Colorbar являются axes объекты ( axes являются родительским классом); мы должны отфильтровать их, потому что оригинальные findall axes findall вернули их!
2

"Jonas" и "tm1" имеют ответы, которые работают для некоторых. Однако, поскольку tm1 указал на проблему, внутри "оси" есть несколько элементов.

Чтобы точно относиться к самой легенде или осям (могут существовать другие предметы), вам нужно их дифференцировать, используя их характерные свойства.

В моем примере я открыл "редактор свойств" и искал разные свойства для осей и легенд (поскольку оба они принадлежат к типу, осям). Я пытался копировать свои топоры и легенду:

copied_axes = findobj(temp_fig,'type','axes','Tag','');
copied_legend = findobj(temp_fig,'type','axes','Tag','legend');

Вместо свойства "Tag" я также мог использовать другое свойство в "Property Inspector". Дело в том, что они должны отличаться. Большинство их свойств одинаковы.

2

Решение Jonas не сработало для меня, потому что были некоторые ручки, относящиеся к легендам. Удивительно, но легенды, похоже, реализованы как оси, по крайней мере, в Matlab 2010a. Вот решение, если вы хотите только оси, а не легенды или другие вещи.

axesHandles = get(fig, 'Children');
classHandles = handle(axesHandles);
count = length(axesHandles);
isNotInstanceOfSubtype = false(1, count);
for i = 1:count
    isNotInstanceOfSubtype(i) = strcmp(class(classHandles(i)), 'axes') == 1;
end
axesHandles = axesHandles(isNotInstanceOfSubtype);

script работает путем сортировки дескрипторов, которые показывают, что они относятся к подтипу осей типа, например scribe.legend.

Предупреждение для тех, кто пытается улучшить приведенный выше фрагмент кода: используя что-то вроде

classHandles = cellfun(@(x) handle(x), axesHandles)

может работать не так, как предполагалось:

??? Error using ==> cellfun
scribe.legend type is not currently implemented.
  • 0
    Вы можете обернуть весь вызов strcmp внутри cellfun / arrayfun (см. мой ответ).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню