Nano Hash - криптовалюты, майнинг, программирование

Легенда влияет только на одну из связанных осей

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

Чтобы построить профиль высоты местности, я использую две оси:

  • ax(1) для неба на заднем плане
  • ax(2) для местности на переднем плане

Вертикальный профиль, легенда

Во время построения графиков я работаю с каждым набором осей независимо, а в конце процесса я связываю ax(1) и ax(2) с помощью linkaxes(ax, 'xy'), чтобы они оставались синхронизированными по размеру.

Наконец, я добавляю legend в положение 'southoutside', но только оси переднего плана автоматически уменьшаются, чтобы освободить место для легенды, оси фона остаются неизменными, что мешает предполагаемому макету, как показано на следующем рисунке:

Вертикальный профиль, легенда, неверные оси

Самой целью использования linkaxes было предотвратить такое нежелательное поведение.

Буду признателен, если кто-нибудь подскажет, как решить эту проблему.


Обновлять

В ответ на комментарий gnovice :

Причина, по которой я использую две оси, заключается в том, что я думал, что это единственный возможный способ объединить разные цветовые карты на одном рисунке. Обратите внимание, что для неба я использую sky_map, а для местности — demcmap. функция, которая устанавливает другую цветовую карту.


Код

% Create figure.
figure;

% Create background axes for the sky.
ax(1) = axes;

% Sky data for background.
x_bg = [0, 0, 10, 10];
y_bg = [0, 10, 10, 0];

% Fill sky with color gradient on y-axis.
fill(x_bg, y_bg, y_bg);

% Generate custom sky colormap.
sky_map = interp1([0, 1], [135, 206, 235; 255, 255, 255]./255, linspace(0, 1, 255));

% Apply sky colormap.
colormap(ax(1), sky_map);

% Create foreground axes for the terrain.
ax(2) = axes;

% Terrain data.
x = [0, 0:10, 10];
y = [0, 5*rand(size(0:10)), 0];

% Fill terrain.
fill(x, y, y);

% Sets the colormap and color axis limits based on the elevation data
% limits.
demcmap(y);

% Link x-axis and y-axis of ax(1) and ax(2).
linkaxes(ax, 'xy');

% Hide ax(1).
set(ax(1), 'Visible', 'off');

% Transparent background for ax(2).
set(ax(2), 'Color', 'none');

% Display title.
title('Vertical Profile');

% Display legend underneath.
legend('Terrain', 'Location', 'southoutside');
23.12.2016

  • linkaxes синхронизирует только оси с ограничениями. Вам потребуется синхронизировать свойства (например, Position) с linkprop. 23.12.2016
  • Спасибо @excaza, вы все правильно поняли! Как вы предложили, я использовал linkprop(ax, 'Position');, и это решило проблему. Я призываю вас опубликовать официальный ответ :) 23.12.2016
  • Я должен спросить... почему ты используешь два топора? Не могли бы вы нанести два заполненных полигона на одни и те же оси, а затем изменить свойство 'ZData' каждого патча, чтобы убедиться, что они правильно наслоены? 23.12.2016
  • @gnovice Большое спасибо за ваш комментарий! На самом деле ваш комментарий очень удобен, потому что, хотя подход excaza решает проблему для этого MVCE, он не работает в моем реальном случае (который более сложный), поэтому пределы двух осей все еще не совпадают в моем реальном кейс. Я использую две оси, потому что думал, что это единственный возможный способ объединить разные цветовые карты на одном рисунке. Работать только с одной осью действительно было бы намного проще. Поскольку я никогда не манипулировал свойством ZData, я не знаю его потенциала. Есть ли какой-нибудь ресурс, на который вы могли бы мне указать? Спасибо еще раз! :) 23.12.2016
  • @Cebri: наличие нескольких объектов, которым нужны свои собственные цветовые карты, сложно, но обычно вы можете обойти это, определив цвета объектов так, чтобы они были цветами RGB, а не индексами цветовой карты. Например, используемая вами команда fill на самом деле просто создает объекты patch, поэтому для фона неба вы можете просто создать объект-заплатку напрямую, уделив особое внимание тому, как вы определяете C входной аргумент. Небо можно было сделать без карты цветов, поэтому местность могла бы использовать ее. 23.12.2016
  • Я включил оба решения в свой ответ ниже. 27.12.2016

Ответы:


1

Вы можете использовать 2 карты цветов на одном рисунке со следующим обходным решением. Основная идея состоит в том, чтобы объединить все карты цветов, которые вы хотите использовать, в одну карту цветов, а затем выбрать, какую часть карты цветов вы используете:

maxHight = 5;
xmax = 10;
% Sky data for background:
x_bg = [0, 0, 1, 1];
y_bg = [0, 1, 1, 0];

% Terrain data:
x = [0 0:xmax xmax];
y = [0 maxHight*rand(size(x(2:end-1))) 0];

% Custom sky colormap:
sky_map = interp1([0, 1], [135, 206, 235; 255, 255, 255]./255, linspace(0, 1, 255));

% Terrain colormap:
tmap = demcmap(y);

% concat both colormaps:
cmap = [tmap;sky_map];

% use the new colormap on the figure:
colormap(cmap);

% Create background axes for the sky:
ax(1) = axes;

% plot the sky as a patch:
patch(x_bg,y_bg,y_bg,'LineStyle','none')

% define the part of the colormap to use:
ax(1).CLim = [-(size(sky_map)/size(cmap)) 1];

% Create foreground axes for the terrain:
ax(2) = axes;

% plot the terrain as a patch:
patch(ax(2),x,y,y)

% define the part of the colormap to use:
ax(2).CLim = [0 max(y)*(size(cmap)/size(tmap))];

% set the limits and axes visibility:
ylim([1 2*maxHight])
ax(1).Visible = 'off';
ax(2).Color = 'none';
linkprop(ax,'position');

% Display title.
title('Vertical Profile');

% Display legend underneath.
legend('Terrain', 'Location', 'southoutside');

который даст вам эту цифру:

Местность

24.12.2016
  • Спасибо за ваш вклад! Я был бы очень признателен, если бы вы могли включить объяснение своего обходного пути. 27.12.2016
  • Пожалуйста. Я добавил некоторые пояснения. Посмотрите здесь для более подробного использования этого метода. 27.12.2016
  • @Cebri, ты понял это решение? это сработало для вас? 28.12.2016
  • Спасибо за добавление комментариев в код. Однако я не мог протестировать все решение, потому что patch(ax(2),x,y,y) выдает: Error using patch. Vectors must be the same length. 28.12.2016
  • @Cebri, вы пытались просто скопировать-вставить-запустить код выше? У меня это работает нормально, и вы сами видите, что и x, и y являются векторами 1 на 13: x = [0, 0:10, 10]; y = [0, maxHight*rand(size(0:10)), 0]; 28.12.2016
  • Да, я скопировал ваш код как есть и получил ошибку. На всякий случай еще раз скопировал, но ошибка все та же. Я согласен, что размеры x и y совпадают, но проблема может быть не в этом. Я использую R2015a. Какую версию ты используешь? 28.12.2016
  • Я использую 2016a, но не вижу существенной разницы. На всякий случай я немного отредактировал приведенный выше код, чтобы сделать его более надежным. 28.12.2016

  • 2

    Способ 1. Использование двух осей и linkprop.

    Цитируя комментарий excaza :

    linkaxes синхронизирует только пределы осей. Вам потребуется синхронизировать свойства (например, Position) с linkprop.

    Добавьте linkprop(ax, 'Position'); перед вызовом legend.

    Результат:

    Способ 1

    В качестве примечания: если вы хотите узнать больше, я предлагаю прочитать «Использование осей ссылок и ссылок. linkprop" из недокументированного Matlab, специально для решения проблемы переопределения linkaxes друг другом.


    Код:

    % Create figure.
    figure;
    
    % Create background axes for the sky.
    ax(1) = axes;
    
    % Sky data for background.
    x_bg = [0, 0, 10, 10];
    y_bg = [0, 10, 10, 0];
    
    % Fill sky with color gradient on y-axis.
    fill(x_bg, y_bg, y_bg);
    
    % Generate custom sky colormap.
    sky_map = interp1([0, 1], [135, 206, 235; 255, 255, 255]./255, linspace(0, 1, 255));
    
    % Apply sky colormap.
    colormap(ax(1), sky_map);
    
    % Create foreground axes for the terrain.
    ax(2) = axes;
    
    % Terrain data.
    x = [0, 0:10, 10];
    y = [0, 5*rand(size(0:10)), 0];
    
    % Fill terrain.
    fill(x, y, y);
    
    % Sets the colormap and color axis limits based on the elevation data
    % limits.
    demcmap(y);
    
    % Link x-axis and y-axis limits of ax(1) and ax(2).
    linkaxes(ax, 'xy');
    
    % Link Position property of ax(1) and ax(2).
    linkprop(ax, 'Position');
    
    % Hide ax(1).
    set(ax(1), 'Visible', 'off');
    
    % Transparent background for ax(2).
    set(ax(2), 'Color', 'none');
    
    % Display title.
    title('Vertical Profile');
    
    % Display legend underneath.
    legend('Terrain', 'Location', 'southoutside');
    

    Способ 2: Использование одной оси и изменение 'FaceVertexCData'

    Цитирование комментариев gnovice 1 и 2:

    Я должен спросить... почему ты используешь два топора? Не могли бы вы нанести два заполненных полигона на одни и те же оси, а затем изменить свойство ZData каждого патча, чтобы убедиться, что они правильно наслоены?

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

    Для части неба замените fill на patch и установите hold on. Затем измените свойство 'FaceVertexCData' с помощью массива значений RGB с истинным цветом (см. Свойства исправления). ).

    В моем коде ниже массив истинного цвета называется CData и определяется:

    % True color array.
    CData = [sky_map(1, :); sky_map(end, :); sky_map(end, :); sky_map(1, :)];
    

    который выглядит так:

    CData =
    
        0.5294    0.8078    0.9216
        1.0000    1.0000    1.0000
        1.0000    1.0000    1.0000
        0.5294    0.8078    0.9216
    

    затем используйте set с дескриптором исправления h1:

    % Apply sky colormap to 'FaceVertexCData' property.
    set(h1, 'FaceVertexCData', CData);
    

    Результат:

    Способ 2


    Код:

    % Create figure.
    figure;
    
    % Sky data for background.
    x_bg = [0, 0, 10, 10];
    y_bg = [0, 10, 10, 0];
    
    % Sky indexed colors.
    c_bg = [0, 1, 1, 0];
    
    % Patch sky using default colormap (parula).
    h1 = patch(x_bg, y_bg, c_bg);
    
    % Generate custom sky colormap.
    sky_map = interp1([0, 1], [135, 206, 235; 255, 255, 255]./255, linspace(0, 1, 255));
    
    % True color array.
    CData = [sky_map(1, :); sky_map(end, :); sky_map(end, :); sky_map(1, :)];
    
    % Apply sky colormap to 'FaceVertexCData' property.
    set(h1, 'FaceVertexCData', CData);
    
    % Retain sky patch in the current axes.
    hold on;
    
    % Terrain data.
    x = [0, 0:10, 10];
    y = [0, 5*rand(size(0:10)), 0];
    
    % Fill terrain.
    h2 = fill(x, y, y);
    
    % Sets the colormap and color axis limits based on the elevation data
    % limits.
    demcmap(y);
    
    % Display title.
    title('Vertical Profile');
    
    % Display legend underneath.
    legend(h2, 'Terrain', 'Location', 'southoutside');
    

    Отличия

    Обратите внимание, что результаты, полученные с помощью метода 1 и метода 2, очень похожи, но не совпадают:

    Способ 1:

    • Чуть меньше фигура.
    • Видны галочки.
    • Серый цвет для фона легенды.

    Способ 2:

    • Чуть крупнее фигура.
    • Галочки не видны.
    • Белый цвет для фона легенды.
    27.12.2016
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..