Як надати гістограму 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.