получить список уже напечатанных этикеток из элементов подзаговора, чтобы избежать двойных записей в легенде - PullRequest
0 голосов
/ 14 января 2019

Рассмотрим эту функцию в Python:

def plots(fields, dev_data, plot_dict, width, color='b', offset=0, l=""):
    ii = 0
    for f in fields:
        ind = np.arange(len(dev_data[ii])) # the x locations for the groups
        import pdb
        plot_dict[f][1].bar(ind + offset, dev_data[ii], width, color=color, label=l, bottom=0)
        if (len(f)>1): #this is used to create a bottom ex. 
            plot_dict[f][1].bar(ind + offset, dev_data[ii+1], width, color='c', label= "free Memory", bottom=dev_data[ii])
            ii += 1
        ii += 1

Он принимает список входных данных (dev_data) и отображает их в виде столбцов. fields - список кортежей, содержащий информацию о данных. Обычно каждый кортеж имеет один элемент, но если он имеет 2, это означает, что 2 последующие данные из dev_data должны быть нанесены друг на друга.

Функция выводит данные на subplots, передаваемые при каждом запуске. Проблема заключается в следующем: если я дважды вызываю plots с одним и тем же списком plt.subfigures, он выполняет эту часть:

           if (len(f)>1): #this is used to create a bottom ex. 
                plot_dict[f][1].bar(ind + offset, dev_data[ii+1], width, color='c', label= "free Memory", bottom=dev_data[ii])
                ii += 1

дважды нанесение метки с одинаковыми значениями дважды, как показано на рисунке.

Чтобы избежать такого поведения, я хочу получить все существующие метки на графике, чтобы, если он уже существовал, я не передавал аргумент label методу bar, что-то вроде:

if (len(f)>1): #this is used to create a bottom ex. 
    if "free Memory" not in plot_dict[f][1].get_existing_labels():
        plot_dict[f][1].bar(ind + offset, dev_data[ii+1], width, color='c', label= "free Memory", bottom=dev_data[ii])
    else:
        plot_dict[f][1].bar(ind + offset, dev_data[ii+1], width, color='c', bottom=dev_data[ii])
    ii += 1

Имеет ли что-то похожее на get_existing_labels Существует для класса осей matplotlib, возвращая, например, ['[0]', '[1]', 'free memory'].?

Надеюсь, мой вопрос понятен. Вот минимально полный и проверяемый пример:

import matplotlib.pyplot as plt
import numpy as np
def plots(fields, dev_data, plot_dict, width, color='b', offset=0, l=""):
    ii = 0
    for f in fields:
        ind = np.arange(len(dev_data[ii])) # the x locations for the groups
        import pdb
        plot_dict[f][1].bar(ind + offset, dev_data[ii], width, color=color, label=l, bottom=0)
        if (len(f)>1): #this is used to create a bottom ex. (RAM_used, RAM_free)
            plot_dict[f][1].bar(ind + offset, dev_data[ii+1], width, color='c', label= "free Memory", bottom=dev_data[ii])
            ii += 1
        ii += 1

fields = [('avg_latency',), ('Successful requests',), ('CPU',), ('RAM', 'free RAM')]
dev_data  = [[8.583309839300817, 171.69371585480965, 1094.40896667813, 189.20147247618982], [100.0, 100.0, 100.0, 100.0], [4.8860107086666815, 35.27584414319996, 76.51036722223547, 41.620512010866655], [1416.4132789999996, 1498.8874527999992, 1825.9473847058837, 3796.161298666671], [4585.911099999997, 4399.862112000003, 3348.1968705882373, 521.1009743727773]]
dev_data2  = [[8.583309839300817, 171.69371585480965, 1094.40896667813, 189.20147247618982], [100.0, 100.0, 100.0, 100.0], [4.8860107086666815, 35.27584414319996, 76.51036722223547, 41.620512010866655], [1416.4132789999996, 1498.8874527999992, 1825.9473847058837, 3796.161298666671], [4585.911099999997, 4399.862112000003, 3348.1968705882373, 521.1009743727773]]

d = list()
d.append(dev_data)
d.append(dev_data2)

colors = ['y','b','r','g','y','c']
plot_d = dict(zip(fields,[ plt.subplots()for l in fields]))
width =0.2
l = ['a','b']
for ii, el in enumerate(d):
    plots(fields, d[ii], plot_d, width, colors[ii], width*(ii-1), [ii])
plt.legend()
plt.show()

legend element shown twice

1 Ответ

0 голосов
/ 14 января 2019

Там действительно существует такая функция, чтобы получить легенды и ручки. Он называется get_legend_handles_labels() и применяется к текущей оси. Это вернет вам маркеры легенды и метки. Первый элемент (индекс [0]) относится к меткам, а второй элемент (индекс [1]) относится к меткам.


В частности, используйте следующие строки кода

import numpy as np
def plots(fields, dev_data, plot_dict, width, color='b', offset=0, l=""):
    ii = 0
    for f in fields:
        ind = np.arange(len(dev_data[ii])) # the x locations for the groups
        import pdb
        plot_dict[f][1].bar(ind + offset, dev_data[ii], width, color=color, label=l, bottom=0)
        if (len(f)>1): #this is used to create a bottom ex. 
            if "free Memory" not in plot_dict[f][1].get_legend_handles_labels()[1]:
                plot_dict[f][1].bar(ind + offset, dev_data[ii+1], width, color='c', label= "free Memory", bottom=dev_data[ii])
            else:
                plot_dict[f][1].bar(ind + offset, dev_data[ii+1], width, color='c', bottom=dev_data[ii])
            ii += 1
        ii += 1

enter image description here

...