Участки участков одинакового (визуального) размера в логарифмическом масштабе c - PullRequest
0 голосов
/ 10 марта 2020

Я хотел бы отметить некоторые пики на графике с логарифмической осью c. Я думал об использовании patch, так как мне нужен обратный вызов, который отвечает, когда пользователь нажимает на маркер. Свойство Vertices для patch указывается в единицах данных, а не в пикселях. Однако я бы хотел, чтобы патчи отображались с одинаковой визуальной шириной и высотой, но я не могу найти способ вычислить ширину (в единицах данных), которая приводит к такой же ширине (в пикселях).

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

Я знаю, что это не просто связано с Matlab, но я ' Я рад использовать что-то еще, кроме patch, при условии, что он предоставляет функциональные возможности реагирования на щелчок мышью.

peakpos = [50 500 5000];
peakheight = [5000 7500 10000];

x = 0:5e4;
y = zeros(numel(x),1);
for k = 1:3
    y(peakpos(k)) = peakheight(k);
end

ax = axes(figure());
plot(ax, x,y);
ax.XScale = 'log';
ax.Units = 'pixels';

dataperpx_y = diff(ax.YLim)/ax.Position(4);

ax.YLim = [0 1e4+30 * dataperpx_y];
ax.NextPlot = 'add';
for k = 1:3
    patch(ax, ...
        'Faces', [1 2 3], ...
        'Vertices', ...
            [ x(peakpos(k)) peakheight(k)+5*dataperpx_y
              x(peakpos(k)) - 25 peakheight(k)+15*dataperpx_y  
              x(peakpos(k)) + 25 peakheight(k)+15*dataperpx_y 
            ], ...
        'ButtonDownFcn', @(h,e)display(h.Vertices));
end

1 Ответ

0 голосов
/ 11 марта 2020

Хорошо, как я и думал, это было не слишком сложно. Я не знаю, где именно я застрял, но одна вещь, которая немного сбивала с толку, заключалась в том, что установка свойства XScale для осей на log заставляет оси использовать десятичные логарифмы c, тогда как функция log() натуральный логарифм

После построения log10(x) в линейном масштабе решение было вполне очевидным:

peakpos = [50 500 5000];
peakheight = [5000 7500 10000];

x = 0:5e4;
y = zeros(numel(x),1);
for k = 1:3
    y(peakpos(k)) = peakheight(k);
end

ax = subplot(2,1,1);

plot(ax, log10(x),y);
%ax.XScale = 'log';
ax.Units = 'pixels';

dataperpx_y = diff(ax.YLim)/ax.Position(4);
dataperpx_x = diff(ax.XLim)/ax.Position(3);
ax.YLim = [0 1e4+30 * dataperpx_y];
ax.NextPlot = 'add';
for k = 1:3
    patch(ax, ...
        'Faces', [1 2 3], ...
        'Vertices', ...
            [ log10(x(peakpos(k))) peakheight(k)+5*dataperpx_y
              log10(x(peakpos(k))) - 5*dataperpx_x peakheight(k)+15*dataperpx_y  
              log10(x(peakpos(k))) + 5*dataperpx_x peakheight(k)+15*dataperpx_y 
            ], ...
        'ButtonDownFcn', @(h,e)display(h.Vertices));
end

ax = subplot(2,1,2);

plot(ax, x, y);
ax.XScale = 'log';
ax.Units = 'pixels';
dataperpx_y = diff(ax.YLim)/ax.Position(4);
dataperpx_x = diff(log10(ax.XLim))/ax.Position(3);
ax.YLim = [0 1e4+30 * dataperpx_y];
ax.NextPlot = 'add';

for k = 1:3
    patch(ax, ...
        'Faces', [1 2 3], ...
        'Vertices', ...
            [ x(peakpos(k)) peakheight(k)+5*dataperpx_y
              x(peakpos(k)) / 10^(5*dataperpx_x) peakheight(k)+15*dataperpx_y  
              x(peakpos(k)) * 10^(5*dataperpx_x) peakheight(k)+15*dataperpx_y 
            ], ...
        'ButtonDownFcn', @(h,e)display(h.Vertices));
end

enter image description here

...