Proposal for Broken Axes


Date: Mon, 15 Mar 2010 13:16:59 -0700 (PDT)
From: klukas <klukas@...45...>

It's my understanding that there is no built-in method for generating a
"broken axis" (where you skip over some range of values, indicating this
with some graphical mark).

I've fudged something similar recently, using a more hacky approach. I
wanted to display a time series with potentially large gaps in its
recording, so I figured out a way to remove the gaps from the plot by
"compacting" the x data, but adjusting the x tick labels to reflect
the original values of the data. Here is an example:

Suppose I have two segments in my time series that are far apart in
time. The segments typically have different lengths. Both the x and y
data are stored as a sequence of 2 arrays (1 per segment), e.g.

x = [ [3, 4, 5, 6, 7, 8, 9], [340, 342, 344, 346, 348] ]
y = [ [ ... ], [ ... ] ]

I only focus on the x (time) axis in this case. I compact the x values
so that the minimum value of the first segment is 0, and the minimum
value of each subsequent segment is equal to the maximum value of the
segment to the left of it. This preserves the relative x-spacing
between the points of the same segment, but shifts the segments to sit
right next to each other. For the above example, I subtract an offset
of 3 for the first segment and 334 for the second segment to get:

compacted_x = [ [0, 1, 2, 3, 4, 5, 6], [6, 8, 10, 12, 14] ]

I then plot the (compacted_x, y) segments as usual on a single Axes,
in my case using a LineCollection. Afterwards, I define a new tick
formatter derived from the standard mpl.ticker.ScalarFormatter that
determines which segment contains the x-value it is called with and
then adds back the appropriate offset before creating the tick label.
I also add dashed vertical "break lines" to indicate the breaks
between segments.

This scheme works especially well for monotonically increasing ticks
(such as time series). I can provide code if anyone is interested.
I've extended it to x and y axes, and it will split image segments in
the same way as line segments (for spectrograms, for example). The
only major current downside is that the cursor displays the compacted
x-value when hovering over the plot (maybe this could be fixed too?).