GNU Octave Matlab: маркировка тиков на графике

Я делаю частотный график, и мне нужна помощь в маркировке тиков. Вот что у меня есть: График частоты

semilogx([200,1000,5000], [0,6,0]);
xlim([20 20000]);
sc = [20:10:100,125:25:175];
scale = [sc,sc*10,sc*100, 20000];
xticks(scale);
xticklabels(scale);
set(gca,'XMinorTick','Off')
grid on;
set (gca, "xminorgrid", "off")
xlabel('frequency (Hz)');
ylabel('dB');
  1. Как я могу сделать так, чтобы все числа от 1000 и выше отображались как 1K, 2K, 5K и так далее?
  2. Как я могу сделать линии на 50 100 200 500, 1K, 2K, 5K, 10K более толстыми/черными?

person lucullus    schedule 05.01.2021    source источник


Ответы (3)


Октавный подход (вероятно, работает и на Matlab)

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

H = semilogx([200,1000,5000], [0,6,0]);
A = gca();
B = axes();

subscale = [20:10:100,125:25:175];
scale    = [subscale,subscale * 10,subscale * 100, 20000];

ScaleTextLabels = {};
for i = 1 : length( scale )
    if scale(i) >= 1000, ScaleTextLabels{i} = sprintf("%dk", scale(i) / 1000 );
    else,                ScaleTextLabels{i} = num2str( scale(i) );
    end
end

SpecialTickLabels   = { '50', '100', '200', '500', '1k', '2k', '5k', '10k'};
ScaleIndices        = 1 : length( ScaleTextLabels );
SpecialIndices      = nthargout( 2, @ismember, SpecialTickLabels, ScaleTextLabels );
NormalIndices       = setdiff( ScaleIndices, SpecialIndices );

set( A, 'xgrid', 'on', 'xlabel', 'frequency (Hz)', 'xlim', [20 20000]      , 'xminorgrid', 'off', 'xminortick', 'off', 'xticklabel', ScaleTextLabels(NormalIndices),  'xtick', scale(NormalIndices) , 'ylabel', 'dB', 'gridlinestyle', ':', 'gridcolor', 'k', 'gridalpha', 0.5 );
set( B, 'xgrid', 'on', 'xlabel', ''              , 'xlim', get( A, 'xlim' ), 'xminorgrid', 'off', 'xminortick', 'off', 'xticklabel', ScaleTextLabels(SpecialIndices), 'xtick', scale(SpecialIndices), 'ylabel', ''  , 'color', 'none', 'fontsize', 12, 'fontweight', 'bold', 'position', get( A, 'position'), 'xcolor', [0,0,0], 'xscale', 'log', 'ylim', get( A, 'ylim'), 'ytick', [], 'gridlinestyle', '--', 'gridcolor', 'k', 'gridalpha', 0.8 );

Этот метод слоев прозрачных объектов осей очень полезен, чтобы иметь в виду в целом, он обеспечивает большую гибкость при разработке сложных графиков. :)

person Tasos Papastylianou    schedule 06.01.2021
comment
Спасибо, Тасо! :) Очень элегантное решение! Знаете ли вы какой-либо способ сделать линии сетки в этих точках более черными? Не могли бы вы взглянуть на мой следующий ответ и посмотреть, как я это сделал, и сказать мне, считаете ли вы, что это хороший способ? Спасибо! (часть, касающаяся линий сетки) - person lucullus; 08.01.2021
comment
@lucullus точно такой же подход, как и выше: поскольку эти линии сетки будут появляться только в тех местах, где находятся «особые» галочки, вы просто устанавливаете «все» стили линий сетки для этого слоя осей черным цветом. На самом деле мне пришлось «схитрить», чтобы они выглядели так же, как и другой слой. Я обновлю свой пример, чтобы показать вам разницу. - person Tasos Papastylianou; 08.01.2021
comment
(сейчас я обновил ответ) - person Tasos Papastylianou; 08.01.2021

В МАТЛАБ

*К сожалению, я пока не нашел, как выделить определенные строки жирным шрифтом

Добавление следующего кода позволяет преобразовывать метки в новые имена/формат, предложенные в части 1. Что касается части 2, лучшее, что я мог узнать прямо сейчас, — это выделение жирным шрифтом конкретных чисел, к сожалению, не конкретных меток/строк. Здесь \bf указывает, какие метки должны быть выделены жирным шрифтом. Все имена будут соответствовать позициям, изначально заданным вашим вектором оси scale. Последняя строка в приведенном ниже коде указывает на замену текущей оси gca.

Настраиваемые оси

semilogx([200,1000,5000],[0,6,0]);
sc = [20:10:100,125:25:175];
scale = [sc,sc*10,sc*100, 20000];

Current_Axis = gca;
Current_Axis.XMinorTick = 'off';
xlabel('frequency (Hz)'); ylabel('dB');
xlim([20 20000]);
grid on;

X_Scale_Names = {'\bf20'; '30'; '40'; '\bf50'; '60';
'70';'80';'90';'\bf100';'125';'150';'175';'\bf200';'300';'400';
'500';'600';'700';'800';'900';'\bf1K';'1.25K';'1.5K';'1.75K';
'\bf2K';'3K';'4K';'\bf5K';'6K';'7K';'8K';'9K';'\bf10K';'12.5K';'15K';
'17.5K';'20K'};

Чтобы настроить дополнительные свойства сетки и оси:

Current_Axis = gca;
set(Current_Axis,'xtick',scale,'xticklabel',X_Scale_Names);
Current_Axis.LineWidth = 1;
Current_Axis.GridColor = 'k';
Current_Axis.GridAlpha = 0.5;

Выполнено с использованием MATLAB R2019b

person MichaelTr7    schedule 05.01.2021
comment
Спасибо за ваши усилия! :) Помогает! Я хотел бы, чтобы галочки и линии сетки были более черными. И мне интересно, есть ли способ автоматизировать процедуру вместо того, чтобы вводить все метки.. Возможно, деление чисел шкалы на 1000, если они = 1000 а затем преобразовать их в строки и добавить после них K? Но я не знаю, можно ли это сделать и как.. - person lucullus; 06.01.2021
comment
Похоже, вы получили потрясающий ответ от другого пользователя, который использует слегка автоматизированный подход. Чтобы конкретные линии/галочки были жирнее, я до сих пор не знаю, как это сделать. Чтобы сделать все галочки более жирными, установите ширину линии текущей оси с помощью set(gca,'linewidth',1);. Я добавил фрагмент кода в свой ответ, чтобы изменить видимость сетки. - person MichaelTr7; 06.01.2021

Я сделал это так:

semilogx([200,1000,5000], [0,6,0]);
xlim([20 20000]);
sc = [20:5:35,40:10:100,125:25:175];
scale = [sc,sc*10,sc*100, 20000];
xticks(scale);
xticklabels(scale);
set(gca,'XMinorTick','Off')
grid on;
set(gca,'gridlinestyle',':');
set(gca,'gridalpha',0.6);
set (gca, "xminorgrid", "off");
xg = [50,100,200,500,1000,2000,5000,10000]; #highlight grids
xx = reshape([xg;xg;NaN(1,length(xg))],1,length(xg)*3);
yy = repmat([ylim() NaN],1,length(xg));
line(xx,yy,'Color',[0.65,0.65,0.65]);
xlabel('frequency (Hz)');
ylabel('dB');
X_Scale_Names = {'\fontsize{11}\bf20'; '25'; '30';'35';'40'; '\fontsize{11}\bf50'; '60';
'70';'80';'90';'\fontsize{11}\bf100';'125';'150';'175';'\fontsize{11}\bf200';'250';'300';'350';'400';
'\fontsize{11}\bf500';'600';'700';'800';'900';'\fontsize{11}\bf1K';'1.25K';'1.5K';'1.75K';
'\fontsize{11}\bf2K';'2.5K';'3K';'3.5K';'4K';'\fontsize{11}\bf5K';'6K';'7K';'8K';'9K';'\fontsize{11}\bf10K';'12.5K';'15K';
'17.5K';'\fontsize{11}\bf20K'};
set(gca,'xtick',scale,'xticklabel',X_Scale_Names);

Но я не думаю, что это лучший/самый быстрый/самый простой способ сделать это...

person lucullus    schedule 06.01.2021