Pandas / matplotlib 막대 그래프 사용자 지정 색상을 제공하는 방법


85

방금 누적 막대 차트를 생성하기 위해 Excel 대신 pandas / matplotlib를 사용하기 시작했습니다. 문제가 발생했습니다

(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)

출력은 다음과 같습니다.

여기에 이미지 설명 입력


부분적인 컬러 맵을 얻는 아주 쉬운 방법이 있습니다. 아래 솔루션을 참조하십시오
Ted Petrou 2017

답변:


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)

사용자 정의 목록을 정의하려면 다음 중 몇 가지를 수행하거나 RGB 값 등으로 색상 항목을 정의하는 Matplotlib 기술을 검색 할 수 있습니다. 원하는대로 복잡해질 수 있습니다.

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 = [cycle ([ 'b', 'r', 'g', 'y', 'k']). next () for i in range (len (df))]는 'b'를 제공합니다. 파이썬 2.7에서 매번. 대신 list (islice (cycle ([ 'b', 'r', 'g', 'y', 'k']), None, len (df)))를 사용해야합니다.
vkontori

고마워요. 아마 못 잡았을 겁니다. 또 다른 옵션은 먼저주기를 만든 다음 next이해 내에서 함수를 호출하는 것입니다.
ely

예. it = cycle ([ 'b', 'r', 'g', 'y', 'k']); my_colors = [I xrange에 대한 다음 (IT) (렌 (DF))]뿐만 아니라, 잘라 것 ...
vkontori

1
오늘 pandas와 matplotlib가 설치되어 있으면 위의 코드는 실행되지만 아무것도 생성하지 않습니다.
kakyo

@kakyo 일반 인터프리터, IPython 또는 셸 (또는 다른 것)에서 실행 중입니까? 이 코드를 실행하는 환경 유형에 따라 matplotlib에 대해 대화 형 모드를 켜거나 pylab.ion()대화 형 pylab에 대해 설정해야 할 수 있습니다 .
ely

52

가장 쉬운 방법은 미리 설정된 색상 그라디언트 중 하나와 함께 colormap매개 변수 를 사용하는 .plot()것입니다.

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

여기에 이미지 설명 입력

여기에서 사전 설정 컬러 맵 의 큰 목록을 찾을 수 있습니다 .

컬러 맵


18
제 경우에는 모든 막대에서 하나의 색상 만 산출합니다
tsando


15

자신 만의 컬러 맵을 만드는 방법에 대한 자세한 답변을 보려면 이 페이지를 방문하는 것이 좋습니다 .

그 대답이 너무 많은 작업이라면 신속하게 고유 한 색상 목록을 만들어 color매개 변수에 전달할 수 있습니다 . 모든 컬러 맵은 cmmatplotlib 모듈에 있습니다. 반전 된 인페르노 컬러 맵에서 30 개의 RGB (알파 포함) 색상 값 목록을 가져옵니다. 이렇게하려면 먼저 컬러 맵을 가져온 다음 0과 1 사이의 값 시퀀스를 전달합니다. 여기서는 np.linspace컬러 맵의 해당 부분을 나타내는 .4와 .8 사이의 균등 간격 값 30 개를 만드는 데 사용 합니다.

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.