Подтвердить что ты не робот

Сюжет разного цвета для разных категориальных уровней с использованием 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)

enter image description here

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

PS:

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

4b9b3361

Ответ 1

Вы можете передать аргумент plt.scatter a 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', вы скажете морскому дну разбить ваш фреймворк на основе ваших цветов, а затем нарисуйте каждый.

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

enter image description here

Без seaborn с помощью pandas.groupby

Если вы не хотите использовать морское дно, вы можете использовать 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).

enter image description here

Ответ 2

Здесь представлено краткое и общее решение для использования палитра с морскими цветами.

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

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

Ответ 3

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

enter image description here

Ответ 4

Используя Альтаир.

from altair import *
import pandas as pd

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

enter image description here

Ответ 5

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

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

Seaborn не будет работать над моим делом, и Altair работает ТОЛЬКО в ноутбуке Jupyter.

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

Ниже приведен код plotnine для репликации вашего примера 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)

plotnine diamonds example

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

Ответ 6

Я обычно делаю это, используя Seaborn, который построен поверх matplotlib

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

Ответ 7

С помощью 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')

plot

С помощью этого метода вам не нужно вручную указывать цвета.

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