4
$\begingroup$

For some seismic data I made a Principal Component Analysis (PCA) of its frequency content:

enter image description here

where the y-axis shows the rank of the principal component, and the numbers on the right show first the amount of data explained by this component and then the cumulative explanation by that component and all below.

The problem now is that each line is normalised, i.e. it runs in [-1 1], and the current representation suggest that the top line actually runs in [9 11], which is misleading.

The question thus is: what would be a representative y-axis for this kind of plot?

Note that I am looking for a theoretical visualisation, although hints as to how to actually implement it would be appreciated. I'm using MATLAB.

$\endgroup$
3
  • 1
    $\begingroup$ This has nothing to do with PCA and would equally apply if your lines were any other functions with the same Y span (in this case [-1,1]), right? $\endgroup$
    – amoeba
    Commented Jul 24, 2018 at 10:01
  • 1
    $\begingroup$ @amoeba true; although the decrease in importance per principal component is important as well, since it defines the order of the lines (which I consider flipping, to have the first PC on the top of the image). $\endgroup$
    – Adriaan
    Commented Jul 24, 2018 at 10:02
  • $\begingroup$ OK, I edited the title. $\endgroup$
    – amoeba
    Commented Jul 24, 2018 at 10:04

3 Answers 3

4
$\begingroup$

I would simply turn off the y axis, and leave the number label next to each plot. You don't need a y axis at all.

Tufte proposed plotting data without axes, if you don't need to read off numbers (like in your case). All that matters is where the stuff happens along the line, you're not comparing amplitudes or anything like that. [BTW, if you don't know of Tufte, I highly recommend you read this book.]

I would also end the x-axis where the data ends, and write the percentages outside the axes (you probably know that text will write outside the axes if you give it coordinates that are outside the axes).

Here's a mock-up of what it would look like:

enter image description here

One more recommendation: invert the order of the principal components, so that the most important one is on top.

$\endgroup$
1
  • 1
    $\begingroup$ This is what I ended up with. Thanks for the good advice $\endgroup$
    – Adriaan
    Commented Jul 26, 2018 at 14:28
2
$\begingroup$

In this situation I would replace the y-axis with a suitable free scale bar indicating the vertical scale for some appropriate unit of data, as below:

enter image description here

Krause, B. M., Murphy, C. A., Uhlrich, D. J., & Banks, M. I. (2017). PV+ Cells Enhance Temporal Population Codes but not Stimulus-Related Timing in Auditory Cortex. Cerebral Cortex.

Since your data are normalized, it would be suitable to label this line with something like [-1 0 1] or [-1 1] at the extreme ends and explain the normalization in the figure caption and paper.

$\endgroup$
1
$\begingroup$

I think the figure is fine as it is, as long as it is explained in a caption. A display like this is actually pretty common for visualizing multi-channel EEG measurements:

EEG plot source: http://neurosoft.com/en/catalog/view/id/37/sid/17

Note that the misinterpretation is avoided here by having text labels instead of numbers on the y-axis. You could do something similar, e.g. "PC1", "PC2" etc. (Matlab: set(gca, 'YTickLabel', ...)). Btw., it might make sense to reverse the order of the y-axis (Matlab: set(gca, 'YDir', 'reverse')).


But if you want to make the figure crystal clear, you need separate axes for the different components:

subplot

In Matlab this can be done via subplot(m,n,p), where m and n denote the number of rows and columns of a grid of subplots (for you, n would be 1), and p is a row-first running index.

Matlab code to generate the above figure:

figure
for i = 1 : N
    subplot(N, 1, i)
    plot(rand(300, 1) * 2 - 1)
    ylabel(num2str(i))
end

According to the comment, you want to avoid the white space around the subplots:

no whitespace

This can be achieved by explicitly positioning them using the syntax subplot('position', [left bottom width height]).

N = 5;
figure
pos = get(gca, 'Position');                    % get standard axis position
subheight = pos(4) / N;                            % compute subplot height
for i = 1 : N
    subpos = pos;
    subpos(4) = subheight;                             % set subplot height
    subpos(2) = subpos(2) + subheight * (N - i);       % set subplot bottom
    subplot('position', subpos)
    plot(rand(300, 1) * 2 - 1)
    ylim([-1.2 1.2])                                 % avoid y-axes overlap
    ylabel(num2str(i))
    if i < N
        set(gca, 'XTickLabel', [])              % remove superfluous x-axes
    end
end

The code also adjusts the subplot's y-axes so that the numbers from different subplots don't overlap.

$\endgroup$
6
  • $\begingroup$ @Adriaan, you didn't mention that in your question! OK, I'll update. $\endgroup$
    – A. Donda
    Commented Jul 24, 2018 at 12:16
  • $\begingroup$ Ah, I didn't because I was open to other solutions, I hadn't thought of anyone actually doing this; I hoped it would be clear a single, concise plot was to be prefered and mainly the y-axis representation is what I'm concerned about. $\endgroup$
    – Adriaan
    Commented Jul 24, 2018 at 12:19
  • $\begingroup$ @Adriaan, is this what you're looking for? $\endgroup$
    – A. Donda
    Commented Jul 24, 2018 at 12:28
  • $\begingroup$ You have to replace 5 by 10 in three different places in my code. Sorry, should have made it with a variable in the first place. $\endgroup$
    – A. Donda
    Commented Jul 24, 2018 at 12:38
  • $\begingroup$ Actually four different places. Changed it. $\endgroup$
    – A. Donda
    Commented Jul 24, 2018 at 12:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.