Авто цвет Seaborn с накоплением гистограммы - PullRequest
0 голосов
/ 01 октября 2019

Я пытаюсь создать столбчатую диаграмму в виде , показанного здесь в seaborn.

import seaborn as sns
import matplotlib.pyplot as plt
sns.set(style="whitegrid")

# Initialize the matplotlib figure
f, ax = plt.subplots(figsize=(6, 15))

# Load the example car crash dataset
crashes = sns.load_dataset("car_crashes").sort_values("total", ascending=False)

# Plot the total crashes
sns.set_color_codes("pastel")
sns.barplot(x="total", y="abbrev", data=crashes,
            label="Total", color="b")

# Plot the crashes where alcohol was involved
sns.set_color_codes("muted")
sns.barplot(x="alcohol", y="abbrev", data=crashes,
            label="Alcohol-involved", color="b")

# Add a legend and informative axis label
ax.legend(ncol=2, loc="lower right", frameon=True)
ax.set(xlim=(0, 24), ylabel="",
       xlabel="Automobile collisions per billion miles")
sns.despine(left=True, bottom=True)

Я заметил в коде, что цвет задается вручную в каждом barplot. Это кажется утомительным, и я знаю, что у морского волка есть некоторые отличные вкусовые оттенки. Как я могу автоматически установить цвета для каждой отдельной серии (стека) при создании гистограммы с накоплением, как показано выше?

Заранее спасибо

Редактировать:

Чтобы ответить навопросы ниже, вот пример сгруппированного графика, когда я не определяю вручную цвет для каждой серии с кодом, который я использовал для его достижения.

enter image description here

f, ax = plt.subplots()

xtics = df.index.astype('str')
sns.color_palette("Set1", n_colors=6, desat=.5)

sns.barplot(xtics, df["Series1"], label="Series1")
sns.barplot(xtics, df["Series2"], bottom=df["Series1"], label="Series2")
sns.barplot(xtics, df["Series3"], bottom=df["Series 2"], label="Series3")
sns.barplot(xtics, df["Series4"], bottom=df["Series3"], label="Series4")
sns.barplot(xtics, df["Series5"], bottom=df["Series4"], label = "Series5")
sns.barplot(xtics, df["Series6"], bottom=df["Series5"], label = "Series6")

ax.legend(ncol=1, frameon=True, loc='upper left',  bbox_to_anchor=(1, 0.5))

ax.set(title="Different Color for Each Bars, Same Color for each series", ylabel="YAxis", xlabel="XAxis")
sns.despine(left=True, bottom=True)

Вот кое-что из того, что я ищу: Фактический цвет не важен, я просто хочу, чтобы они были разными для каждой серии без ручного выбора каждого цвета самостоятельно. Обратите внимание на color= в приведенном ниже коде.

enter image description here

f, ax = plt.subplots()

xtics = df.index.astype('str')
sns.color_palette("Set1", n_colors=6, desat=.5)

sns.barplot(xtics, df["Series1"], label="Series1", color="#000000")
sns.barplot(xtics, df["Series2"], bottom=df["Series1"], label="Series2", color="#004949")
sns.barplot(xtics, df["Series3"], bottom=df["Series 2"], label="Series3", color="#009292")
sns.barplot(xtics, df["Series4"], bottom=df["Series3"], label="Series4", color="#ff6db6")
sns.barplot(xtics, df["Series5"], bottom=df["Series4"], label = "Series5", color="#490092")
sns.barplot(xtics, df["Series6"], bottom=df["Series5"], label = "Series6", color="#ffb6db")

ax.legend(ncol=1, frameon=True, loc='upper left',  bbox_to_anchor=(1, 0.5))

ax.set(title="Different Color for Each Bars, Same Color for each series", ylabel="YAxis", xlabel="XAxis")
sns.despine(left=True, bottom=True)

1 Ответ

1 голос
/ 02 октября 2019

Я бы просто использовал список цветов и использовал бы цикл или итератор указанного списка и использовал бы его так:

np.random.seed(1234)
N_series = 6
N_bars = 4
xticks = ['2016', '2017', '2018', '2019']
df = pd.DataFrame({f'Series{i+1}': np.random.randint(1,10,size=(N_bars,)) for i in range(N_series)}, index=xticks)

colors = iter(sns.color_palette('Set1', n_colors=N_series, desat=.75))

fig, ax = plt.subplots()
ax.bar(xticks, df["Series1"], bottom=0, label="Series1", color=next(colors))
ax.bar(xticks, df["Series2"], bottom=df["Series1"], label="Series2", color=next(colors))
ax.bar(xticks, df["Series3"], bottom=df["Series2"]+df["Series1"], label="Series3", color=next(colors))
ax.bar(xticks, df["Series4"], bottom=df["Series3"]+df["Series2"]+df["Series1"], label="Series4", color=next(colors))
ax.bar(xticks, df["Series5"], bottom=df["Series4"]+df["Series3"]+df["Series2"]+df["Series1"], label="Series5", color=next(colors))
ax.bar(xticks, df["Series6"], bottom=df["Series5"]+df["Series4"]+df["Series3"]+df["Series2"]+df["Series1"], label="Series6", color=next(colors))

ax.legend(ncol=1, frameon=True, loc='upper left',  bbox_to_anchor=(1, 0.5))
ax.set(title="Same Color for each series", ylabel="YAxis", xlabel="XAxis")
sns.despine(left=True, bottom=True)

enter image description here

PS

  • Почему вы хотите использовать морского рожка, если вы, кажется, не используете его каким-либо образом, отличным от plt.bar()? В моем примере я использовал bar() напрямую, но вы получили бы тот же результат, если бы вы заменили на sns.barplot()
  • , в ваших аргументах bottom= произошла ошибка, вы должны указать суммуиз всех столбцов ниже, чтобы получить желаемый результат
...