построить разные цвета для разных категорийных уровней, используя matplotlib

У меня есть этот фрейм данных diamonds, который состоит из таких переменных, как (carat, price, color), и я хочу нарисовать диаграмму рассеяния от price до carat для каждого color, что означает, что разные color имеют разный цвет на графике.

Это легко сделать в R с 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)

введите описание изображения здесь

Интересно, как это можно сделать в Python с помощью matplotlib?

PS:

Я знаю о вспомогательных пакетах построения графиков, таких как seaborn и ggplot for python, и я не предпочитаю их, просто хочу узнать, можно ли выполнить эту работу, используя только matplotlib,; P


person avocado    schedule 01.10.2014    source источник


Ответы (7)


Импорт и образец DataFrame

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns  # for sample data
from matplotlib.lines import Line2D  # for legend handle

# DataFrame used for all options
df = sns.load_dataset('diamonds')

   carat      cut color clarity  depth  table  price     x     y     z
0   0.23    Ideal     E     SI2   61.5   55.0    326  3.95  3.98  2.43
1   0.21  Premium     E     SI1   59.8   61.0    326  3.89  3.84  2.31
2   0.23     Good     E     VS1   56.9   65.0    327  4.05  4.07  2.31

С matplotlib

Вы можете передать plt.scatter аргумент c, который позволяет вам выбрать цвета. Следующий код определяет словарь colors для сопоставления цветов ромба с цветами печати.

fig, ax = plt.subplots(figsize=(6, 6))

colors = {'D':'tab:blue', 'E':'tab:orange', 'F':'tab:green', 'G':'tab:red', 'H':'tab:purple', 'I':'tab:brown', 'J':'tab:pink'}

ax.scatter(df['carat'], df['price'], c=df['color'].map(colors))

# add a legend
handles = [Line2D([0], [0], marker='o', color='w', markerfacecolor=v, label=k, markersize=8) for k, v in colors.items()]
ax.legend(title='color', handles=handles, bbox_to_anchor=(1.05, 1), loc='upper left')

plt.show()

df['color'].map(colors) эффективно отображает цвета от ромба до черчения.

(Простите меня за то, что я не поместил еще один пример изображения, я думаю, что двух достаточно: P)

С seaborn

Вы можете использовать seaborn, который является оболочкой для matplotlib, которая по умолчанию делает его красивее (скорее, на основе мнения, я знаю: P), но также добавляет некоторые функции построения графиков.

Для этого вы можете использовать seaborn.lmplot. с fit_reg=False (что предотвращает автоматическое выполнение некоторой регрессии).

  • sns.scatterplot(x='carat', y='price', data=df, hue='color', ec=None) тоже делает то же самое.

Выбор hue='color' указывает seaborn на разделение и построение данных на основе уникальных значений в столбце 'color'.

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

введите описание изображения здесь

С помощью pandas.DataFrame.groupby & _ 18_

Если вы не хотите использовать seaborn, используйте pandas.groupby, чтобы получить только цвета, а затем нарисуйте их, используя только matplotlib, но вам придется вручную назначать цвета по ходу работы, я добавил пример ниже:

fig, ax = plt.subplots(figsize=(6, 6))

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) с реальным цветом (например, tab:blue).

введите описание изображения здесь

person Ffisegydd    schedule 01.10.2014

Вот краткое и универсальное решение для использования цветовой палитры морского дна.

Сначала найдите понравившуюся цветовую палитру и, при желании, визуализируйте ее:

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))
person Rems    schedule 23.03.2017

У меня был тот же вопрос, и я провел весь день, пробуя разные пакеты.

Изначально я использовал matlibplot: и меня не устраивало сопоставление категорий с предопределенными цветами; или группировка / агрегация, а затем итерация по группам (и при этом все еще необходимо отображать цвета). Я просто почувствовал, что это плохая реализация пакета.

Сиборн не работал бы в моем случае, а Альтаир работает ТОЛЬКО внутри Jupyter Notebook.

Лучшим решением для меня был PlotNine, который «представляет собой реализацию грамматики графики на Python, основанную на ggplot2».

Ниже приведен программный код для репликации вашего примера R на Python:

from plotnine import *
from plotnine.data import diamonds

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

Пример с бриллиантами

Так чисто и просто :)

person deprekate    schedule 08.05.2019

Используя Altair.

from altair import *
import pandas as pd

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

введите описание изображения здесь

person Nipun Batra    schedule 06.07.2017

Вот комбинация маркеров и цветов из качественной палитры в 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);

введите здесь описание изображения

person Pablo Reyes    schedule 14.04.2017

С df.plot ()

Обычно при быстром построении DataFrame я использую pd.DataFrame.plot(). Это принимает индекс как значение x, значение как значение y и отображает каждый столбец отдельно с другим цветом. DataFrame в этой форме может быть получен с помощью set_index и 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')

сюжет

При использовании этого метода вам не нужно вручную указывать цвета.

Эта процедура может иметь больше смысла для других рядов данных. В моем случае у меня есть данные таймсерий, поэтому MultiIndex состоит из datetime и категорий. Также можно использовать этот подход для более чем одного столбца для раскрашивания, но легенда становится беспорядочной.

person Simon    schedule 13.08.2019

Вы можете преобразовать категориальный столбец в числовой с помощью команд:

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

#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) 
person chaitanya ashish    schedule 06.10.2020