# What would be an appropriate Y axis when plotting several functions shifted one under another?

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

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.

• 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? Commented Jul 24, 2018 at 10:01
• @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). Commented Jul 24, 2018 at 10:02
• OK, I edited the title. Commented Jul 24, 2018 at 10:04

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:

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

• This is what I ended up with. Thanks for the good advice Commented Jul 26, 2018 at 14:28

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:

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.

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:

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:

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:

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.

• @Adriaan, you didn't mention that in your question! OK, I'll update. Commented Jul 24, 2018 at 12:16
• 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. Commented Jul 24, 2018 at 12:19
• @Adriaan, is this what you're looking for? Commented Jul 24, 2018 at 12:28
• 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. Commented Jul 24, 2018 at 12:38
• Actually four different places. Changed it. Commented Jul 24, 2018 at 12:40