Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib's build-in interval plot

I'm trying to plot multi intervals for multiple entries.

I've tried using a loop to enumerate over the entries, plotting one interval at a time.

import matplotlib.pyplot as plt

intervals = [(1, 2), (1.1, 2.5), (1.2, 4), (1.5, 10), (1.7, 12)]

num_intervals = len(intervals)
viridis = plt.cm.get_cmap('viridis', num_intervals)

fig, ax = plt.subplots()
for idx, (min_int, max_int) in enumerate(intervals):
  ax.hlines(y=idx, xmin=min_int, xmax=max_int, colors=viridis(idx / num_intervals), label=idx)
ax.legend()
plt.yticks([], [])
plt.show()

plot

I wish to use matplotlib's build-in method for plotting multiple intervals all at once. Also, I wish to plot the min and max values for each interval in the image.

I wish to add min & max values annotations to the lines as such: min & max values annotations

like image 861
user5618793 Avatar asked Oct 19 '25 11:10

user5618793


1 Answers

You can tweak your code to be able to use LineCollection whose idea is outlined in this answer. Furthermore, you can add the legends to the LineCollection using this approach.

I modified the first answer to create the lines input data in the desired format using list comprehension.

from matplotlib.lines import Line2D # Imported for legends

num_intervals = len(intervals)
viridis = plt.cm.get_cmap('viridis', num_intervals)
colors = np.array([viridis(idx / num_intervals) for idx in range(len(intervals))])

# Prepare the input data in correct format for LineCollection 
lines = [[(i[0], j), (i[1], j)] for i, j in zip(intervals, range(len(intervals)))]

lc = mc.LineCollection(lines, colors= colors, linewidths=2)
fig, ax = pl.subplots()
ax.add_collection(lc)
ax.margins(0.1)
plt.yticks([], [])

# Adding the legends
def make_proxy(col, scalar_mappable, **kwargs):
    color = col 
    return Line2D([0, 1], [0, 1], color=color, **kwargs)
proxies = [make_proxy(c, lc, linewidth=2) for c in colors]
ax.legend(proxies, range(5))

# Adding annotations
for i, x in enumerate(intervals):
    plt.text(x[0], i+0.1, x[0], color=colors[i])
    plt.text(x[1], i+0.1, x[1], color=colors[i])

enter image description here

like image 141
Sheldore Avatar answered Oct 21 '25 02:10

Sheldore