У меня есть 3 списка, каждый из которых содержит числа, представляющие время. Время представляет событие. Например, в этом A
у меня есть число для каждого события события A
. Я хочу представить эти данные на графике. Одним из следующих двух способов:
Ответ 2
В качестве дополнения к предыдущим ответам вы можете использовать plt.hbar
:
import matplotlib.pyplot as plt
import numpy as np
import string
x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
y = np.array([0, 0, 1, 0, 0, 0, 1, 1, 2, 2, 0, 2, 0, 2])
labels = np.array(list(string.uppercase))
plt.barh(y, [1]*len(x), left=x, color = 'red', edgecolor = 'red', align='center', height=1)
plt.ylim(max(y)+0.5, min(y)-0.5)
plt.yticks(np.arange(y.max()+1), labels)
plt.show()
![enter image description here]()
Или вы можете попробовать что-то вроде этого:
import matplotlib.pyplot as plt
import numpy as np
data = [[1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0],
[0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 3, 0, 3]]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.axes.get_yaxis().set_visible(False)
ax.set_aspect(1)
def avg(a, b):
return (a + b) / 2.0
for y, row in enumerate(data):
for x, col in enumerate(row):
x1 = [x, x+1]
y1 = np.array([y, y])
y2 = y1+1
if col == 1:
plt.fill_between(x1, y1, y2=y2, color='red')
plt.text(avg(x1[0], x1[1]), avg(y1[0], y2[0]), "A",
horizontalalignment='center',
verticalalignment='center')
if col == 2:
plt.fill_between(x1, y1, y2=y2, color='orange')
plt.text(avg(x1[0], x1[0]+1), avg(y1[0], y2[0]), "B",
horizontalalignment='center',
verticalalignment='center')
if col == 3:
plt.fill_between(x1, y1, y2=y2, color='yellow')
plt.text(avg(x1[0], x1[0]+1), avg(y1[0], y2[0]), "C",
horizontalalignment='center',
verticalalignment='center')
plt.ylim(3, 0)
plt.show()
![enter image description here]()
Если вы хотите, чтобы все слоты находились в одной строке, сделайте несколько изменений, как показано ниже:
import matplotlib.pyplot as plt
import numpy as np
data = [[1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0],
[0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 3, 0, 3]]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.axes.get_yaxis().set_visible(False)
ax.set_aspect(1)
def avg(a, b):
return (a + b) / 2.0
for y, row in enumerate(data):
for x, col in enumerate(row):
x1 = [x, x+1]
y1 = [0, 0]
y2 = [1, 1]
if col == 1:
plt.fill_between(x1, y1, y2=y2, color='red')
plt.text(avg(x1[0], x1[1]), avg(y1[0], y2[0]), "A",
horizontalalignment='center',
verticalalignment='center')
if col == 2:
plt.fill_between(x1, y1, y2=y2, color='orange')
plt.text(avg(x1[0], x1[0]+1), avg(y1[0], y2[0]), "B",
horizontalalignment='center',
verticalalignment='center')
if col == 3:
plt.fill_between(x1, y1, y2=y2, color='yellow')
plt.text(avg(x1[0], x1[0]+1), avg(y1[0], y2[0]), "C",
horizontalalignment='center',
verticalalignment='center')
plt.ylim(1, 0)
plt.show()
![enter image description here]()
Второй и третий варианты - это больше кода, но они дают намного лучшие результаты.
Ответ 5
Создание и упрощение последнего графика @amillerrhodes (также удаление текстовой части):
import matplotlib.pyplot as plt
import numpy as np
# run-length encoding, instead of a list of lists with a bunch of zeros
data = [(2, 1), (1, 2), (3, 1), (2, 2), (2, 3), (1, 1), (1, 3), (1, 1), (1, 3)]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.axes.get_yaxis().set_visible(False)
ax.set_aspect(1)
for i, (num, cat) in enumerate(data):
if i > 0:
x_start += data[i-1][0] # get previous end position
else:
x_start = i # start from 0
x1 = [x_start, x_start+num]
y1 = [0, 0]
y2 = [1, 1]
if cat == 1:
plt.fill_between(x1, y1, y2=y2, color='red')
if cat == 2:
plt.fill_between(x1, y1, y2=y2, color='orange')
if cat == 3:
plt.fill_between(x1, y1, y2=y2, color='yellow')
plt.ylim(1, 0)
plt.show()
![введите описание изображения здесь]()