matplotlib를 사용하여 다양한 범주 수준에 대해 다른 색을 플로팅합니다.


102

나는 diamonds같은 변수로 구성된 이 데이터 프레임 을 가지고 있으며 각 에 대한 (carat, price, color)산점도를 그리려고합니다. 즉 , 플롯에서 다른 색상 이 있음을 의미 합니다.pricecaratcolorcolor

이것은 다음 Rggplot같이 쉽습니다 .

ggplot(aes(x=carat, y=price, color=color),  #by setting color=color, ggplot automatically draw in different colors
       data=diamonds) + geom_point(stat='summary', fun.y=median)

여기에 이미지 설명 입력

나는 이것을 사용하여 파이썬에서 어떻게 할 수 있는지 궁금합니다 matplotlib.

추신:

seaborn및과 같은 보조 플로팅 패키지에 대해 알고 있지만 ggplot for python선호하지 않습니다 matplotlib.; P를 사용하여 작업을 수행 할 수 있는지 확인하고 싶습니다 .


1
matplotlib에 이와 같은 것이 내장되어 있으면 정말 좋겠지 만 쉽지는 않을 것 같습니다. 이상 여기 토론 : github.com/matplotlib/matplotlib/issues/6214
naught101

답변:


156

색상을 선택할 수 plt.scatter있는 c인수를 전달할 수 있습니다 . 아래 코드는 colors다이아몬드 색상을 플로팅 색상에 매핑 하는 사전을 정의합니다 .

import matplotlib.pyplot as plt
import pandas as pd

carat = [5, 10, 20, 30, 5, 10, 20, 30, 5, 10, 20, 30]
price = [100, 100, 200, 200, 300, 300, 400, 400, 500, 500, 600, 600]
color =['D', 'D', 'D', 'E', 'E', 'E', 'F', 'F', 'F', 'G', 'G', 'G',]

df = pd.DataFrame(dict(carat=carat, price=price, color=color))

fig, ax = plt.subplots()

colors = {'D':'red', 'E':'blue', 'F':'green', 'G':'black'}

ax.scatter(df['carat'], df['price'], c=df['color'].apply(lambda x: colors[x]))

plt.show()

df['color'].apply(lambda x: colors[x]) "다이아몬드"에서 "플로팅"으로 색상을 효과적으로 매핑합니다.

(다른 예제 이미지를 올리지 않은 것에 대해 용서하십시오. 2면 충분하다고 생각합니다. : P)

seaborn

기본적으로 더 예쁘게 보이게 만드는 seaborn래퍼를 사용할 수 있지만 matplotlib(오피니언 기반, 나는 알고 있습니다 : P) 일부 플로팅 기능도 추가합니다.

이를 위해 seaborn.lmplot함께 사용할 수 있습니다 fit_reg=False(이는 일부 회귀를 자동으로 수행하는 것을 방지합니다).

아래 코드는 예시 데이터 세트를 사용합니다. 선택 hue='color'하면 seaborn에게 색상을 기준으로 데이터 프레임을 분할 한 다음 각각을 플로팅하도록 지시합니다.

import matplotlib.pyplot as plt
import seaborn as sns

import pandas as pd

carat = [5, 10, 20, 30, 5, 10, 20, 30, 5, 10, 20, 30]
price = [100, 100, 200, 200, 300, 300, 400, 400, 500, 500, 600, 600]
color =['D', 'D', 'D', 'E', 'E', 'E', 'F', 'F', 'F', 'G', 'G', 'G',]

df = pd.DataFrame(dict(carat=carat, price=price, color=color))

sns.lmplot('carat', 'price', data=df, hue='color', fit_reg=False)

plt.show()

여기에 이미지 설명 입력

seaborn사용 하지 않고pandas.groupby

seaborn을 사용하지 않으려면 pandas.groupby색상 만 가져온 다음 matplotlib를 사용하여 플로팅 할 수 있지만 이동하면서 수동으로 색상을 할당해야합니다. 아래 예제를 추가했습니다.

fig, ax = plt.subplots()

colors = {'D':'red', 'E':'blue', 'F':'green', 'G':'black'}

grouped = df.groupby('color')
for key, group in grouped:
    group.plot(ax=ax, kind='scatter', x='carat', y='price', label=key, color=colors[key])

plt.show()

이 코드는 위와 동일한 DataFrame을 가정하고 color. 그런 다음 이러한 그룹을 반복하여 각 그룹에 대해 플로팅합니다. 색상을 선택하기 colors위해 다이아몬드 색상 (예 D:)을 실제 색상 ( 예 :)에 매핑 할 수 있는 사전을 만들었습니다 red.

여기에 이미지 설명 입력


감사합니다.하지만 matplotlib만으로 작업을 수행하는 방법을 찾고 싶습니다.
아보카도

예, groupby그렇게 할 수 있으므로 matplotlib다른 색상을 사용하여 카테고리의 다른 수준에 대해 자동으로 그릴 수 있는 기능 이 있습니다.
아보카도

@loganecolss Ok I see :) 나는 그것을 다시 편집하고 예제와 유사하게 사전을 사용하여 색상을 매핑하는 매우 간단한 예제를 추가했습니다 groupby.
Ffisegydd

1
@Ffisegydd 첫 번째 방법 인을 사용하여 ax.scatter범례를 어떻게 추가 하시겠습니까? 내가 사용하려고 label=df['color']다음과 plt.legend()성공하지.
ahoosh

1
그것은 변화에 더 좋을 것이다 ax.scatter(df['carat'], df['price'], c=df['color'].apply(lambda x: colors[x]))ax.scatter(df['carat'], df['price'], c=df['color'].map(colors)
부부장

33

다음은 seaborn 색상 팔레트를 사용하는 간결하고 일반적인 솔루션입니다.

먼저 원하는 색상 팔레트찾아 선택적으로 시각화하십시오.

sns.palplot(sns.color_palette("Set2", 8))

그런 다음 다음과 같이 사용할 수 있습니다 matplotlib.

# Unique category labels: 'D', 'F', 'G', ...
color_labels = df['color'].unique()

# List of RGB triplets
rgb_values = sns.color_palette("Set2", 8)

# Map label to RGB
color_map = dict(zip(color_labels, rgb_values))

# Finally use the mapped values
plt.scatter(df['carat'], df['price'], c=df['color'].map(color_map))

2
나는 당신의 접근 방식을 좋아합니다. 위의 예에서 값을 다음과 같은 간단한 색상 이름에 매핑 할 수도 있습니다. 1) 색상 정의 색상 = { 'D': 'red', 'E': 'blue', 'F': 'green ','G ':'black '} 2) 당신이했던 것처럼 매핑 : ax.scatter (df ['carat '], df ['price '], c = df ['color ']. map (colors))
Stefan

1
하지만이 경우 색상별로 라벨을 어떻게 추가 하시겠습니까?
François Leblanc

2
좀 더 추상화를 추가하려면 8in sns.color_palette("Set2", 8)len(color_labels).
Swier

이것은 훌륭하지만 seaborn에 의해 자동으로 수행되어야합니다. 무언가를 빠르게 그릴 때마다 범주 형 변수에 대한 맵을 사용해야하는 것은 매우 방해가됩니다. 플롯에 통계를 표시하는 기능을 꺼내는 멍청한 아이디어는 말할 것도 없습니다. Seaborn은 불행히도 이러한 이유로 인해 패키지로 감소하고 있습니다
chase

8

나는 같은 질문이 있었고 하루 종일 다른 패키지를 시험해 보았습니다.

저는 원래 matlibplot을 사용했습니다 : 그리고 미리 정의 된 색상에 대한 범주 매핑에 만족하지 않았습니다. 또는 그룹화 / 집계 한 다음 그룹을 반복합니다 (그리고 여전히 색상을 매핑해야 함). 패키지 구현이 좋지 않다고 느꼈습니다.

Seaborn은 내 케이스에서 작동하지 않으며 Altair는 Jupyter Notebook 내부에서만 작동합니다.

저에게 가장 적합한 솔루션은 PlotNine이었습니다. "Python에서 그래픽 문법을 구현 한 ggplot2 기반"입니다.

다음은 Python에서 R 예제를 복제하는 플롯 나인 코드입니다.

from plotnine import *
from plotnine.data import diamonds

g = ggplot(diamonds, aes(x='carat', y='price', color='color')) + geom_point(stat='summary')
print(g)

plotnine 다이아몬드 예

너무 깨끗하고 간단합니다 :)


질문 matplotlib
Chuck

6

Altair 사용 .

from altair import *
import pandas as pd

df = datasets.load_dataset('iris')
Chart(df).mark_point().encode(x='petalLength',y='sepalLength', color='species')

여기에 이미지 설명 입력


질문 matplotlib
Chuck

5

다음은 정 성적 컬러 맵의 마커와 색상 조합입니다 matplotlib.

import itertools
import numpy as np
from matplotlib import markers
import matplotlib.pyplot as plt

m_styles = markers.MarkerStyle.markers
N = 60
colormap = plt.cm.Dark2.colors  # Qualitative colormap
for i, (marker, color) in zip(range(N), itertools.product(m_styles, colormap)):
    plt.scatter(*np.random.random(2), color=color, marker=marker, label=i)
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0., ncol=4);

여기에 이미지 설명 입력


에서이 mpl.cm.Dark2.colors- mpl코드에 정의하지 않는 것, 그리고 Dark2속성이 없습니다 colors.
Shovalt

@Shovalt 검토해 주셔서 감사합니다. 나는 수입해야 matplotlib로서 mpl내가 사용하여 내 코드를 수정 한 plt도 포함한다 cm. 적어도 matplotlib내가 2.0.0을 사용 하고있는 버전 Dark2에는 속성이 있습니다colors
Pablo Reyes

1
당신이없는 경우 늦은하지만 색상 속성 : ITER는 (plt.cm.Dark2 (np.linspace (0, 1, N)))
제프 Lentsch

3

df.plot () 사용

일반적으로 DataFrame을 빠르게 플로팅 할 때 pd.DataFrame.plot(). 인덱스를 x 값으로, 값을 y 값으로 취하고 각 열을 다른 색상으로 개별적으로 플로팅합니다. 이 형태의 DataFrame을 사용하여 달성 될 수 set_indexunstack.

import matplotlib.pyplot as plt
import pandas as pd

carat = [5, 10, 20, 30, 5, 10, 20, 30, 5, 10, 20, 30]
price = [100, 100, 200, 200, 300, 300, 400, 400, 500, 500, 600, 600]
color =['D', 'D', 'D', 'E', 'E', 'E', 'F', 'F', 'F', 'G', 'G', 'G',]

df = pd.DataFrame(dict(carat=carat, price=price, color=color))

df.set_index(['color', 'carat']).unstack('color')['price'].plot(style='o')
plt.ylabel('price')

음모

이 방법을 사용하면 색상을 수동으로 지정할 필요가 없습니다.

이 절차는 다른 데이터 시리즈에 더 적합 할 수 있습니다. 제 경우에는 timeseries 데이터가 있으므로 MultiIndex는 datetime과 범주로 구성됩니다. 하나 이상의 열에 색상을 지정하는 데이 방법을 사용할 수도 있지만 범례가 엉망이되고 있습니다.


0

저는 보통 matplotlib 위에 구축 된 Seaborn을 사용하여합니다.

import seaborn as sns
iris = sns.load_dataset('iris')
sns.scatterplot(x='sepal_length', y='sepal_width',
              hue='species', data=iris); 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.