2016-07-02 4 views
1

У меня есть очень простая сгруппированная диаграмма с 5 группами по 4 бара каждый. Я использовал пример из matplotlib documentation, который выглядит следующим образом:matplotlib: Как совместить несколько баров с линиями

import numpy as np 
import matplotlib.pyplot as plt 

ind = np.arange(5) 
avg_bar1 = (81191,79318,57965,60557,14793) 
avg_bar2 = (26826,26615,31364,31088,55472) 
avg_bar3 = (36232,38038,38615,39014,40812) 
avg_bar4 = (26115,25879,25887,28326,27988) 

fig, ax = plt.subplots() 

rects1 = ax.bar(ind, avg_bar1, 0.15, label='bar1') 
rects2 = ax.bar(ind + 0.15, avg_bar2, 0.15, label='bar2') 
rects3 = ax.bar(ind + 0.30, avg_bar3, 0.15, label='bar2') 
rects4 = ax.bar(ind + 0.45, avg_bar4, 0.15, label='bar2') 

plt.xlabel('Distributions') 
plt.ylabel('ms') 
plt.xticks(ind + 0.15, ('50/50', '60/40', '70/30', '80/20', '90/10')) 
plt.legend() 

plt.tight_layout() 
plt.show() 

Проблема

Но некоторые значения баров в соответствующих других групп (например, планкой1 в group1 и планкой1 в group2 и т.д.) не сильно отличаются друг от друга.

То, что я хочу

Так что я хочу добавить строки для того, чтобы увидеть тенденцию каждой группы более четко. Линии должны идти от верхней части каждого бара в одной группе до верхней части панели в соответствующих других группах.

В Интернете я не нашел ничего подобного.

Возможно ли это?

ответ

0

Спасибо @arsho для входа. Я сделал это немного более компактным. Он также исправил ошибку в последней группе баров вашего кода. См. Комментарии в коде. Надеюсь это поможет.

Для таких, как я, которые являются новыми для matplotlib: мы можем просто построить линию к подзаголовку, независимо от того, содержит ли он уже бары.

import numpy as np 
import matplotlib.pyplot as plt 

# fig, is the whole thing; ax1 is a subplot in the figure, 
# so we reference it to plot bars and lines there 
fig, ax1 = plt.subplots() 

ind = np.arange(3) 
width = 0.15 

# per dimension 
colors = ['#00ff00', '#0000ff', '#ff00ff'] 
markers = ['x','o','v'] 
xticklabels = ['50/50', '60/40', '70/30'] 

# 
group1 = [12,6,5] 
group2 = [6,8,12] 
group3 = [2,4,9] 

# 
all_groups = [ group1, group2, group3 ] 

# plot each group of bars; loop-variable bar_values contains values for bars 
for i, bar_values in enumerate(all_groups): 

    # compute position for each bar 
    bar_position = width*i 
    ax1.bar(ind + bar_position, bar_values, width, color=colors[i]) 

# plot line for each group of bars; loop-variable y_values contains values for lines 
for i, y_values in enumerate(all_groups): 

    # moves the beginning of a line to the middle of the bar 
    additional_space = (width*i) + (width/2); 
    # x_values contains list indices plus additional space 
    x_values = [ x + additional_space for x,_ in enumerate(y_values) ] 

    # simply plot the values in y_values 
    ax1.plot(x_values, y_values, marker=markers[i], color=colors[i]) 

plt.setp([ax1], xticks=ind + width, xticklabels=xticklabels) 

plt.tight_layout() 
plt.show() 
1

Я начал изучать Matplotlib и Numpy недавно и нашел ваш вопрос весьма интересен.

Итак, я трачу время на создание комбинированного графика сгруппированной гистограммы и линейной диаграммы, относящейся к этой группированной диаграмме.

Результат: enter image description here

Код:

import numpy as np 
import matplotlib.pyplot as plt 

ind = np.arange(5) 
avg_bar1 = (81191,79318,57965,60557,14793) 
avg_bar2 = (26826,26615,31364,31088,55472) 
avg_bar3 = (36232,38038,38615,39014,40812) 
avg_bar4 = (26115,25879,25887,28326,27988) 

rects1 = plt.bar(ind, avg_bar1, 0.15, color='#ff0000',label='bar1') 
rects2 = plt.bar(ind + 0.15, avg_bar2, 0.15, color='#00ff00', label='bar2') 
rects3 = plt.bar(ind + 0.30, avg_bar3, 0.15, color='#0000ff', label='bar3') 
rects4 = plt.bar(ind + 0.45, avg_bar4, 0.15, color='#000000', label='bar4') 

high_point_x = [] 
high_point_y = []  
for i in range(0,5): 
    single_bar_group={rects1[i].get_height():rects1[i].get_x() + rects1[i].get_width()/2.0, 
         rects2[i].get_height():rects2[i].get_x() + rects2[i].get_width()/2.0, 
         rects3[i].get_height():rects3[i].get_x() + rects3[i].get_width()/2.0, 
         rects4[i].get_height():rects4[i].get_x() + rects4[i].get_width()/2.0} 

    height_list = list(single_bar_group.keys()) 
    height_list.sort(reverse=True) 
    for single_height in height_list: 
     high_point_y.append(single_height) 
     high_point_x.append(single_bar_group[single_height]) 
     break 

trend_line = plt.plot(high_point_x,high_point_y,marker='o', color='#5b74a8', label='Trend Line') 

plt.xlabel('Distributions') 
plt.ylabel('ms') 
plt.xticks(ind+0.15, ('50/50', '60/40', '70/30', '80/20', '90/10')) 
plt.legend() 
plt.show() 
Смежные вопросы