matlabplotoctavelabelingxticks

GNU Octave Matlab: Plot tick labeling


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?

Solution

  • 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. :)