Как настроить пользовательские цвета <bar> pandas/matplotlib
Я только начал использовать 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)
И вывод следующий:
![enter image description here]()
Ответы
Ответ 1
Вы можете указать опцию 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.
Последний пример дает следующий простой градиент цветов для меня:
![enter image description here]()
Я не играл с ним достаточно долго, чтобы понять, как заставить легенду подобрать определенные цвета, но я уверен, что вы можете это сделать.
В целом, однако, большой совет - просто использовать функции от Matplotlib напрямую. Вызов из Pandas в порядке, но я нахожу, что вы получаете лучшие варианты и производительность, вызывая их прямо из Matplotlib.
Ответ 2
Я нашел, что самый простой способ - использовать параметр colormap
в .plot()
с одним из предустановленных цветовых градиентов:
df.plot(kind='bar', stacked=True, colormap='Paired')
![введите описание изображения здесь]()
Здесь вы можете найти большой список предустановленных цветовых папок.
![colormaps]()
Ответ 3
Для получения более подробного ответа на создание собственных цветовых карт я настоятельно рекомендую посетить эту страницу
Если этот ответ слишком большой, вы можете быстро составить свой собственный список цветов и передать их параметру color
. Все цветовые палитры находятся в модуле matplotlib cm
. Позвольте получить список из 30 значений цвета RGB (плюс альфа) из измененной цветовой схемы inferno. Для этого сначала получите цветовой код и передайте ему последовательность значений между 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))
![введите описание изображения здесь]()