How to plot interrupted horizontal lines (segments) in matplotlib in a "cheap way" without using NaNs?
Asked Answered
U

1

5

I have to plot several "curves", each one composed by horizontal segments (or even points), using matplotlib library.

A random example of plot. Marker points can be omitted

I reached this goal separing the segments by NaNs. This is my example (working) code:

from pylab import arange, randint, hold, plot, show, nan, ylim, legend

n = 6
L = 25
hold(True)
for i in range(n):
    x = arange(L, dtype=float)  # generates a 1xL array of floats
    m = randint(1, L)
    x[randint(1, L, m)] = nan  # set m values as NaN
    y = [n - i] * len(x)  #  constant y value
    plot(x, y, '.-')

leg = ['data_{}'.format(j+1) for j in range(n)]
legend(leg)
ylim(0, i + 2)
show()

(actually, I start from lists of integers: NaNs are added after where integers are missing)

Problem: since each line requires an array of length L, this solution can be expensive in terms of memory if L is big, while the necessary and sufficient information are the limits of segments.

For example, for one line composed by 2 segments of limits (0, 500) and (915, 62000) it would be nice to do something like this:

niceplot([(0, 500), (915, 62000)], [(1, 1), (1, 1)])

(note: this - with plot instead niceplot... - is a working code but it makes other things...)

4*2 values instead of 62000*2... Any suggestions?

(this is my first question, be clement^^)

Unstable answered 5/9, 2012 at 23:10 Comment(2)
Take a look at the hlines function.Hilarius
@WarrenWeckesser: I think yours it's the best answer.Unstable
I
7

Is this something like what you wish to achieve?

import matplotlib.pyplot as plt

segments = {1: [(0, 500),
                (915, 1000)],
            2: [(0, 250),
                (500, 1000)]}

colors = {1: 'b', 2: 'r'}

for y in segments:
    col = colors.get(y, 'k')
    for seg in segments[y]:
        plt.plot(seg, [y, y], color=col)

I'm just defining the y values as keys and a list of line segments (xlo, xhi) to be plotted at each y value.

Intercede answered 6/9, 2012 at 0:9 Comment(2)
Nice. Needed only one color per plot (I made that change)Unstable
@Unstable I didn't like the change you made to my code snippet, since it breaks when the segments are defined for more than the fixed number of colors you defined. I edited so it won't break for those cases.Intercede

© 2022 - 2024 — McMap. All rights reserved.