Matplotlib, легенды не появляются в гистограмме - PullRequest
3 голосов
/ 28 апреля 2019

чтобы описать мою проблему, я привожу вам небольшой набор данных в качестве примера: представьте следующий набор данных:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
df = pd.DataFrame({'name':['a', 'b', 'c', 'a', 'b', 'c'], 'val':[1,5,3,4,5,3]} )

Я создаю простую гистогаму со следующим кодом:

def plot_bar_x():
    index = np.arange(len(df['name']))
    plt.bar(index, df['val'])
    plt.legend(list(df['name'].unique()))
    plt.xticks(index, df['name'], fontsize=10, rotation=30)
    plt.show()
plot_bar_x()

Но это дает мне следующий сюжет: enter image description here

Хотя у меня есть 3 уникальных имени, но я вижу только метку 'a', однако я использовал эту строку: plt.legend (list (df['name']. unique ())) другая проблема в том, что все полосы имеют одинаковый цвет, есть ли способ получить разные цвета для уникальных этикеток без предварительного определения цветов вручную?

желаемый выводэто:

enter image description here

Ответы [ 2 ]

1 голос
/ 28 апреля 2019

Вы можете напрямую построить DataFrame, используя df.plot(), а затем передать цвета каждой панели, используя некоторый предопределенный словарь.Затем вы можете создавать легенды, используя mpatches.Patch, как показано здесь .Вы можете использовать seaborn, чтобы иметь сероватый фон с сетками.Цвета могут быть сгенерированы в зависимости от количества уникальных элементов в кадре данных.

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import pandas as pd
import numpy as np; np.random.seed(123)
import seaborn as sns
sns.set()

df = pd.DataFrame({'name':['a', 'b', 'c', 'a', 'b', 'c'], 'val':[1,5,3,4,5,3]} )
col_dict = {k:np.random.rand(3,) for k in df['name'].unique()}

ax = df.plot.bar(x='name', y='val', color=[col_dict[i] for i in df['name']])
labels = [mpatches.Patch(color=v, label=k) for k,v in col_dict.items()]
plt.legend(handles=labels, loc='best')    
plt.show()

enter image description here

1 голос
/ 28 апреля 2019

Вы только один раз наносите сюжет на одну серию, поэтому plt выбирает только одну метку для легенды. Если у вас мало имен, попробуйте:

def plot_bar_x():
    index = np.arange(len(df['name']))
    plt.figure()
    for name in df.name.unique():
        tmp_df = df[df.name == name]
        plt.bar(tmp_df.index, tmp_df.val, label=name)
    plt.xticks(index, df['name'], fontsize=10, rotation=30)
    plt.legend()
    plt.show()

Должен быть какой-то умный способ решить твою проблему, но это сейчас над моей головой.

...