matplotlib kullanarak farklı kategorik seviyeler için farklı renkler çizin


104

Bu veri çerçevesi var diamondsgibi değişkenler oluşur (carat, price, color), ve ben serpme çizim çizmek istiyorum priceiçin carather biri için colorfarklı anlamı, colorarsa farklı rengi vardır.

Bu kolaydır Rile ggplot:

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)

görüntü açıklamasını buraya girin

Bunu kullanarak Python yapılabilir acaba matplotlib?

Not:

Böyle gibi yardımcı çizim paketleri, hakkında bilmek seabornve ggplot for pythonve ben sadece kullanarak iş yapmak mümkün olup olmadığını öğrenmek istiyorum, onları tercih yapmıyorsanız matplotlibyalnız, P


1
Matplotlib'de böyle bir şeyin yerleşik olması gerçekten güzel olurdu, ama kulağa kolay olmayacak gibi geliyor. Tartışma burada: github.com/matplotlib/matplotlib/issues/6214
naught101

Yanıtlar:


159

Renkleri seçmenize izin verecek plt.scatterbir cargüman iletebilirsiniz . Aşağıdaki kod colors, elmas renklerinizi çizim renkleriyle eşlemek için bir sözlük tanımlar .

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]) renkleri "elmas" dan "çizim" e etkili bir şekilde eşler.

(Başka bir örnek resim koymadığım için beni affet, bence 2 yeterli: P)

İle seaborn

Varsayılan olarak daha güzel görünmesini sağlayan seabornbir sarmalayıcı olanı kullanabilirsiniz matplotlib(daha ziyade fikir temelli, biliyorum: P) ama aynı zamanda bazı çizim işlevleri de ekler.

Bunun için seaborn.lmplotile kullanabilirsiniz fit_reg=False(bu, otomatik olarak bir miktar gerileme yapmasını engeller).

Aşağıdaki kod, örnek bir veri kümesi kullanır. Seçerek hue='color'size renklere dayalı dataframe bölmek ve ardından her biri çizmek için Seaborn söyle.

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

görüntü açıklamasını buraya girin

olmadan seabornkullanarakpandas.groupby

Seaborn'u kullanmak istemiyorsanız kullanabilirsiniz pandas.groupby , renkleri tek başına elde ve sonra bunları sadece matplotlib kullanarak çizebilirsiniz, ancak ilerledikçe renkleri manuel olarak atamanız gerekecek, aşağıya bir örnek ekledim:

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

Bu kod, yukarıdaki ile aynı DataFrame'i varsayar ve ardından onu temel alarak gruplandırır color. Daha sonra bu gruplar üzerinde yineleyerek her biri için çizim yapar. Bir renk seçmek için colors, elmas rengini (örneğin D) gerçek bir renge ( örneğin ) eşleyebilen bir sözlük oluşturdum red.

görüntü açıklamasını buraya girin


Teşekkürler, ama işi sadece matplotlib ile nasıl yapacağımı öğrenmek istiyorum.
avokado

Evet, aracılığıyla groupbybunu yapabilirim, böylece matplotlibfarklı renk kullanarak bir kategorikinin farklı seviyelerini otomatik olarak çizebilen bir özellik var , değil mi?
avokado

@loganecolss Tamam görüyorum :) Tekrar düzenledim ve örneğe benzer şekilde renkleri eşleştirmek için sözlük kullanan çok basit bir örnek ekledim groupby.
Ffisegydd

1
@Ffisegydd İlk metodu kullanarak ax.scatterefsaneleri nasıl eklersiniz? Kullanmaya çalışıyorum label=df['color']ve sonra plt.legend()da başarılı olamadım.
ahoosh

2
Bu değişim daha iyi olurdu ax.scatter(df['carat'], df['price'], c=df['color'].apply(lambda x: colors[x]))içinax.scatter(df['carat'], df['price'], c=df['color'].map(colors)
Dawai

40

İşte deniz kenarı renk paleti kullanmak için kısa ve genel bir çözüm.

Önce beğendiğiniz bir renk paleti bulun ve isteğe bağlı olarak görselleştirin:

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

O zaman bunu matplotlibyaparak kullanabilirsiniz :

# 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
Yaklaşımını beğendim. Yukarıdaki örnekte, değerleri elbette basit renk adlarıyla da eşleyebilirsiniz: 1) renkleri tanımlayın = {'D': 'kırmızı', 'E': 'mavi', 'F': 'yeşil ',' G ':' siyah '} 2) bunları yaptığınız gibi eşleyin: ax.scatter (df [' karat '], df [' fiyat '], c = df [' renk ']. Harita (renkler))
Stefan

1
Yine de bu durumda bir etiketi renge göre nasıl eklersiniz?
François Leblanc

3
Biraz daha soyutlama eklemek için, yerini alabilir 8in sns.color_palette("Set2", 8)tarafından len(color_labels).
Swier

Bu harika, ancak seaborn tarafından otomatik olarak yapılmalıdır. Bir şeyi hızlı bir şekilde çizmek istediğiniz her seferinde kategorik değişkenler için bir harita kullanmak zorunda olmak , inanılmaz derecede engelleyicidir. Olay örgüsünde istatistikleri gösterme yeteneğini ortadan kaldırmanın aptalca fikrinden bahsetmiyorum bile. Seaborn maalesef bu nedenlerden dolayı paket olarak reddediliyor
takip edin

7

Aynı soruyu sormuştum ve bütün günümü farklı paketleri deneyerek geçirdim.

Başlangıçta matlibplot kullanmıştım: ve kategorileri önceden tanımlanmış renklerle eşlemekten memnun değildim; veya gruplama / toplama, sonra gruplar arasında yineleme (ve yine de renkleri eşlemek zorunda). Paket uygulamasının zayıf olduğunu hissettim.

Seaborn benim durumumda işe yaramazdı ve Altair YALNIZCA Jupyter Not Defterinin içinde çalışıyor.

Benim için en iyi çözüm, "Python'da grafiklerin gramerinin bir uygulaması olan ve ggplot2'yi temel alan" PlotNine idi.

Python'da R örneğinizi çoğaltmak için plotnine kodu aşağıdadı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 elmas örneği

Çok temiz ve basit :)


Matplotlib
Chuck

6

Altair'i kullanma .

from altair import *
import pandas as pd

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

görüntü açıklamasını buraya girin


Matplotlib
Chuck

5

Burada kalitatif bir renk haritasından işaretçiler ve renklerin bir kombinasyonu 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);

görüntü açıklamasını buraya girin


In mpl.cm.Dark2.colors- mplkodunuzda tanımlı görünmüyor ve Dark2özniteliği yok colors.
Shovalt

@Shovalt İnceleme için teşekkürler. Ben ithal gerekirdi matplotlibolarak mplben kullanarak kodumu düzelttikten, pltayrıca içeren cm. En azından kullandığım matplotlibsürümde 2.0.0 Dark2özniteliğe sahipcolors
Pablo Reyes,

1
Geç, ancak colors özniteliğine sahip değilseniz: iter (plt.cm.Dark2 (np.linspace (0,1, N)))
Geoff Lentsch

3

Df.plot () ile

Normalde bir DataFrame'i hızlı bir şekilde çizerken, pd.DataFrame.plot() . Bu, indeksi x değeri, değeri y değeri olarak alır ve her sütunu farklı bir renkle ayrı ayrı çizer. Bu formdaki bir DataFrame, set_indexve kullanılarak elde edilebilir unstack.

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

arsa

Bu yöntemle renkleri manuel olarak belirtmeniz gerekmez.

Bu prosedür diğer veri serileri için daha mantıklı olabilir. Benim durumumda zaman serisi verilerim var, bu nedenle MultiIndex datetime ve kategorilerden oluşuyor. Bu yaklaşımı birden fazla sütunun renklendirmesi için kullanmak da mümkündür, ancak efsane karmakarışık hale geliyor.


0

Bunu genellikle matplotlib üzerine kurulu Seaborn kullanarak yapıyorum.

import seaborn as sns
iris = sns.load_dataset('iris')
sns.scatterplot(x='sepal_length', y='sepal_width',
              hue='species', data=iris); 

0

Aşağıdaki komutları kullanarak kategorik sütunu sayısal bir sütuna dönüştürebilirsiniz:

#we converting it into categorical data
cat_col = df['column_name'].astype('categorical') 

#we are getting codes for it 
cat_col = cat_col.cat.codes 

# we are using c parameter to change the color.
plt.scatter(df['column1'],df['column2'], c=cat_col) 

İhtiyaç duyabileceğinizi astype('category')unutmayın categorical.
j6m8
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.