Як надати гістограму pandas / matplotlib власні кольори


85

Я щойно почав використовувати pandas / matplotlib як заміну Excel для створення накопичених гістограм. Я стикаюся з проблемою

(1) у картці кольорів за замовчуванням лише 5 кольорів, тому якщо у мене більше 5 категорій, кольори повторюються. Як я можу вказати більше кольорів? В ідеалі, градієнт із початковим та кінцевим кольорами та спосіб динамічного генерування n кольорів між ними?

(2) кольори не дуже візуально приємні. Як вказати власний набір із n кольорів? Або градієнт також буде працювати.

Приклад, який ілюструє обидва вищезазначені пункти, наведений нижче:

  4 from matplotlib import pyplot
  5 from pandas import *
  6 import random
  7 
  8 x = [{i:random.randint(1,5)} for i in range(10)]
  9 df = DataFrame(x)
 10 
 11 df.plot(kind='bar', stacked=True)

І результат такий:

введіть тут опис зображення


Існує досить простий спосіб отримати часткову карту кольорів. Дивіться це рішення нижче
Тед Петру,

Відповіді:


118

Ви можете вказати colorопцію як список безпосередньо для plotфункції.

from matplotlib import pyplot as plt
from itertools import cycle, islice
import pandas, numpy as np  # I find np.random.randint to be better

# Make the data
x = [{i:np.random.randint(1,5)} for i in range(10)]
df = pandas.DataFrame(x)

# Make a list by cycling through the colors you care about
# to match the length of your data.
my_colors = list(islice(cycle(['b', 'r', 'g', 'y', 'k']), None, len(df)))

# Specify this list of colors as the `color` option to `plot`.
df.plot(kind='bar', stacked=True, color=my_colors)

Щоб визначити власний власний список, ви можете зробити кілька з наведеного нижче, або просто переглянути методи Matplotlib для визначення елемента кольору за його значеннями RGB тощо. Ви можете зробити з цим все, що завгодно.

my_colors = ['g', 'b']*5 # <-- this concatenates the list to itself 5 times.
my_colors = [(0.5,0.4,0.5), (0.75, 0.75, 0.25)]*5 # <-- make two custom RGBs and repeat/alternate them over all the bar elements.
my_colors = [(x/10.0, x/20.0, 0.75) for x in range(len(df))] # <-- Quick gradient example along the Red/Green dimensions.

Останній приклад дає такий простий градієнт кольорів для мене:

введіть тут опис зображення

Я не грався з ним досить довго, щоб зрозуміти, як змусити легенду підібрати визначені кольори, але я впевнений, що ви можете це зробити.

Загалом, однак, велика порада - просто використовувати функції Matplotlib безпосередньо. Зателефонувати їм з Pandas це нормально, але я вважаю, що ви отримуєте кращі варіанти та продуктивність, зателефонувавши їм прямо з Matplotlib.


3
Невелика помилка: my_colors = [цикл (['b', 'r', 'g', 'y', 'k']). Next () для i в діапазоні (len (df))] дасть "b" кожного разу в python 2.7. Замість цього слід використовувати list (islice (цикл (['b', 'r', 'g', 'y', 'k']), None, len (df))).
vkontori

Дякую, мабуть, я б цього не впіймав. Інший варіант - спочатку створити цикл, а потім просто викликати його nextфункцію всередині розуміння.
Елі,

Так. it = цикл (['b', 'r', 'g', 'y', 'k']); my_colors = [next (it) for i in xrange (len (df))] також скоротить і це ...
vkontori

1
З сьогодні встановленими pandas та matplotlib код вище для мене нічого не генерує, хоча він працює.
kakyo 07.03.15

@kakyo Ви працюєте в звичайному інтерпретаторі, IPython або з оболонки (чи чогось іншого)? Залежно від того, в якому типі середовища ви виконуєте цей код, можливо, вам доведеться ввімкнути інтерактивний режим для matplotlib або встановити pylab.ion()для інтерактивного пілабу.
ely

52

Я виявив, що найпростіший спосіб - використовувати colormapпараметр в .plot()одному з попередньо заданих кольорових градієнтів:

df.plot(kind='bar', stacked=True, colormap='Paired')

введіть тут опис зображення

Тут ви можете знайти великий список попередньо встановлених кольорових карт .

кольорові карти


18
у моєму випадку це дає лише один колір на всіх барах
tsando

Я знайшов ці списки кольорових карт корисними matplotlib.org/examples/color/colormaps_reference.html gallantlab.github.io/colormaps.html
Al Po

15

Щоб отримати більш детальну відповідь щодо створення власних кольорових карт, настійно рекомендую відвідати цю сторінку

Якщо ця відповідь занадто багато роботи, ви можете швидко скласти власний список кольорів і передати їх colorпараметру. Всі кольорові карти знаходяться в cmмодулі matplotlib. Давайте отримаємо список із 30 значень кольору RGB (плюс альфа) із зворотної карти кольорів пекла. Для цього спочатку отримайте карту кольорів, а потім передайте їй послідовність значень від 0 до 1. Тут ми використовуємо np.linspaceдля створення 30 рівномірно розташованих значень між .4 і .8, які представляють цю частину кольорової карти.

from matplotlib import cm
color = cm.inferno_r(np.linspace(.4, .8, 30))
color

array([[ 0.865006,  0.316822,  0.226055,  1.      ],
       [ 0.851384,  0.30226 ,  0.239636,  1.      ],
       [ 0.832299,  0.283913,  0.257383,  1.      ],
       [ 0.817341,  0.270954,  0.27039 ,  1.      ],
       [ 0.796607,  0.254728,  0.287264,  1.      ],
       [ 0.775059,  0.239667,  0.303526,  1.      ],
       [ 0.758422,  0.229097,  0.315266,  1.      ],
       [ 0.735683,  0.215906,  0.330245,  1.      ],
       .....

Тоді ми можемо використовувати це для побудови графіку, використовуючи дані з вихідного повідомлення:

import random
x = [{i: random.randint(1, 5)} for i in range(30)]
df = pd.DataFrame(x)
df.plot(kind='bar', stacked=True, color=color, legend=False, figsize=(12, 4))

введіть тут опис зображення


2
Ось документація до інших кольорових карт, крім inferno_r: matplotlib.org/examples/color/colormaps_reference.html
tsando

1
Я дотримувався цього фрагмента, але мій масив кольорів завжди має однакові значення.
FaCoffee
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.