Цвета выбираются из палитры цветов с бесконечной цикличностью :
palette = itertools.cycle(sns.color_palette(palette=sns.colors.crayons))
sns.lineplot(..., color=next(palette))
...
sns.violinplot(..., color=next(palette))
Каждый раз, когда вызывается next(palette)
, возвращается следующий цвет из цикла.Таким образом, не существует цветовой окраски между линейными сюжетами и скрипками (если только по чудесному совпадению или по замыслу len(data.columns)
не кратно len(sns.colors.crayons)
).
Один способ получить цвета линейной сюжета и скрипкибыть скоординированным, это сбросить палитру перед каждым циклом:
palette = sns.color_palette(palette=sns.crayon_palette(sns.colors.crayons))
new_palette = itertools.cycle(palette)
for i in data: # Loop over all columns except 'Location'
...
sns.lineplot(x=data.index, y=i, data=data, color=next(new_palette))
...
new_palette = itertools.cycle(palette)
for i in data: # Loop over all columns
...
sns.violinplot(y=i, data=data, color=next(new_palette))
Вверху, palette
- это просто список.new_palette
- бесконечно циклический итератор.Создавая new_palette
перед каждым for-loop
, next(new_palette)
будет возвращать одинаковые цвета в одинаковом порядке для обоих for-loop
с.
В качестве альтернативы, возможно, более простым способом достижения желаемого результата являетсяобъедините два цикла for в один, чтобы вы могли вызывать lineplot
и vionlinplot
в одной и той же итерации и передавать один и тот же цвет для обоих вызовов функций.Разбиение кода на функции может помочь прояснить смысл кода и сохранить его аккуратным.
import itertools
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
def make_data():
data = [{'Time': '201501', 'type1': 100, 'type2': 200, 'type3': 300},
{'Time': '201502', 'type1': 150, 'type2': 250, 'type3': 350},
{'Time': '201503', 'type1': 300, 'type2': 300, 'type3': 300},
{'Time': '201504', 'type1': 350, 'type2': 350, 'type3': 350}]
data = pd.DataFrame(data)
data['Time'] = pd.to_datetime(data['Time'], format='%Y%m')
data.set_index(['Time'], inplace=True)
data = data.astype(float)
return data
def make_lineplot(data, i, color):
fig, ax = plt.subplots()
sns.set(style="ticks")
sns.lineplot(x=data.index, y=i, data=data, color=color)
sns.despine(offset=10, trim=True)
fig.set_size_inches(18, 12)
ax.set_title('{} History'.format(i), fontweight='bold')
plt.savefig('{}.pdf'.format(i), bbox_inches='tight')
def make_violinplot(data, i, color):
fig, ax = plt.subplots()
sns.set(style="ticks")
sns.violinplot(y=i, data=data, color=color)
sns.despine(offset=10, trim=True)
fig.set_size_inches(18, 12)
ax.set_title('{} Violin Plot'.format(i), fontweight='bold')
plt.savefig('{}_violin.pdf'.format(i), bbox_inches='tight')
data = make_data()
palette = itertools.cycle(sns.color_palette(palette=sns.colors.crayons))
# I had to use the line below to get the code to run
# palette = itertools.cycle(sns.color_palette(palette=sns.crayon_palette(sns.colors.crayons)))
for i, color in zip(data, palette):
make_lineplot(data, i, color)
make_violinplot(data, i, color)