首页 > 解决方案 > 在情节中重用颜色

问题描述

我在 Jupyter 笔记本中有一个项目,我正在比较两个数据帧。两者都按年份编制索引,并且都具有相同的列,表示人口中宗教信仰者的比例。这两个数据框代表两个不同的群体。

我希望能够在同一个线图中显示两组数据,每种宗教使用相同的颜色,但一个人口的线条是实心的,而另一个人口的线条是虚线。

我以为我可以做这样的事情:

ax1.plot(area1_df, color=[col1,col2,col3,col4])
ax1.plot(area2_df, color=[col1,col2,col3,col4], ls=':',alpha=0.5, linewidth=3.0)

但这不起作用。

目前我有这个:

import matplotlib.pyplot as plt

fig, ax1 = plt.subplots(1,1, sharex = True, sharey=True, figsize=(15,5))
plt.style.use('seaborn')

ax1.plot(area1_df);
ax1.plot(area2_df, ls=':',alpha=0.5, linewidth=3.0);

ax1.legend(area1_df.keys(), loc=2)
ax1.set_ylabel('% of population')
plt.tight_layout()

也许还有另一种方法可以完全做到这一点(?)

关于如何最好地创建统一图例的任何想法的奖励积分,以及来自两个数据框的列的条目。

标签: pythonmatplotlibjupyter-notebook

解决方案


要为每条线赋予特定的颜色,您可以捕获ax1.plot并遍历该线列表的输出。每条线都可以被赋予它的颜色。也是传说的标签。

以下代码首先生成一些玩具数据,然后遍历两个绘图的线。使用分配的标签创建具有两列的图例。

import numpy as np
import pandas as pd
import matplotlib.pylab as plt

years = np.arange(1990, 2021, 1)
N = years.size
area1_df = pd.DataFrame({f'group {i}': 10+i+np.random.uniform(-1, 1, N).cumsum() for i in range(1, 5)}, index=years)
area2_df = pd.DataFrame({f'group {i}': 10+i+np.random.uniform(-1, 1, N).cumsum() for i in range(1, 5)}, index=years)

fig, ax1 = plt.subplots(figsize=(15,5))
plot1 = ax1.plot(area1_df)
plot2 = ax1.plot(area2_df, ls=':',alpha=0.5, linewidth=3.0)
for l1, l2, label1, label2, color in zip(plot1, plot2, area1_df.columns, area2_df.columns,
                                         ['crimson', 'limegreen', 'dodgerblue', 'turquoise']):
    l1.set_color(color)
    l1.set_label(label1)
    l2.set_color(color)
    l2.set_label(label2)
ax1.legend(ncol=2, title='area1 / area2')
plt.show()

示例图

或者,您可以通过 pandas 进行绘图,它允许为每列分配颜色:

fig, ax1 = plt.subplots(figsize=(15, 5))
colors = plt.cm.Dark2.colors
area1_df.plot(color=colors, ax=ax1)
area2_df.plot(color=colors, ls=':', alpha=0.5, linewidth=3.0, ax=ax1)
ax1.legend(ncol=2, title='area1 / area2')

推荐阅读