3

I am making a frequency plot and I would like some help on tick labeling. Here is what I have: Frequency plot

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. How can I make all numbers from 1000 and upwards appear as 1K, 2K, 5K and so on?
  2. How could I make the lines on 50,100,200,500,1K,2K,5K,10K appear thicker/more black?
lucullus
  • 187
  • 1
  • 11

3 Answers3

3

In MATLAB

*I unfortunately could not yet find how to bold the specific lines

Adding the following code allows the ticks to converted to the new names/format suggested in part 1. For part 2 the best I could find out right now is bolding the specific numbers, unfortunately not the specific ticks/lines. Here \bf indicates which labels are to be bolded. All the names will correspond to the positions set originally by your axis vector scale. The last line in the code below indicates the replacement of the current axis, gca.

Customized Axes

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'};

To Adjust More Grid and Axis Properties:

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;

Ran using MATLAB R2019b

MichaelTr7
  • 4,737
  • 2
  • 6
  • 21
  • Thank you for your effort! :) It helps! I would like to have the ticks and the grid lines more black.. And I wonder if there is any way to automate the procedure instead of having to type all the labels.. Maybe dividing the scale numbers by 1000 if they are >=1000 and then converting them to strings and adding a K after them? But I don't know if this could be done and how.. – lucullus Jan 06 '21 at 11:34
  • 1
    Looks like you got an amazing answer from another user that uses a slightly automated approach. For specific lines/ticks to be bolder I'm still not sure how to do it. To make all the ticks bolder setting the current axis' line width by using `set(gca,'linewidth',1);` will do the trick. I've added a code snippet in my answer to change the grid visibility. – MichaelTr7 Jan 06 '21 at 16:07
3

Octave approach (probably works on matlab too though)

I wouldn't rely on latex trickery to do this to be honest.
Here is the way I usually do stuff like this.
Effectively, because the axis labels object is considered a single object, and you cannot split it into parts, the trick is to overlay an invisible, bare-minimum axes object defining only the labels you want, and treat those as you'd like (e.g. adjust its fontweight, fontsize, xcolor, etc etc).

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 );

This "layers of transparent axes objects" technique is very useful to keep in mind in general, it allows great flexibility when designing complex graphs. :)

Tasos Papastylianou
  • 21,371
  • 2
  • 28
  • 57
  • Thank you Taso! :) Very elegant solution! Do you know of any way to make the grid lines at those ticks blacker? Could you have a look at my next answer and see how I found it to be done and tell me if you think is a good way? Thanks! (the part regarding the grid lines) – lucullus Jan 08 '21 at 11:54
  • 1
    @lucullus exactly the same approach as above: since these grid lines will only appear at the places where the 'special' ticks are, you simply set 'all' gridlinestyles for that axes layer to black. In fact, I had to 'cheat' to make them look the same as the other layer. I'll update my example to show you the difference. – Tasos Papastylianou Jan 08 '21 at 13:43
1

I did it like this:

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);

But I don't think this is the best/fastest/easiest way to do it...

lucullus
  • 187
  • 1
  • 11