【问题标题】:Consistent colors among bar plots条形图中颜色一致
【发布时间】:2021-07-24 16:26:50
【问题描述】:

我有一个数据集,其中每一列是一个国家,每一行是一年,我想显示,以便以后建立条形图竞赛,每年排名前 5 的国家以及它们如何随时间变化。

为了做到这一点,我希望每个国家/地区每年都有相同的条形颜色,即使它们在年份之间改变位置。这就是为什么我对数据进行排名并将它们的排名用于 y 位置,而不是对其进行排序。

当我运行以下代码时,前 3 个条形图(1996 年到 1998 年)中的国家颜色是一致的,即使其中一个改变了位置,但从 1999 年到 2001 年,每个国家/地区都会改变颜色,直到 2001 年保持一致。

# Plotting several time periods, with ranking
dates = [1996, 1997, 1998, 1999, 2000, 2001]

# How many elements to show in each graph...
topN = 5

# Plot grid
fig, ax_array = plt.subplots(nrows = 1, ncols = 6, figsize = (10, 2.5), dpi = 144, tight_layout = True)

for ax, date in zip(ax_array, dates):

    # Series with desired date
    s = exp_data_wide.loc[date]
    # Rank every country, then drop NaN values
    s_rank = s.rank(method = 'first').dropna()

    # X and Y values for the graphic
    # Since I've got a large list of countries, and I must avoid sorting the data, I work with the last N values of the rank
    y = s_rank[s_rank >= len(s_rank) - topN]
    x = s[y.index]

    ax.barh (y = y, width = x.values, color = colors, tick_label = x.index)
    ax.set_title(date, fontsize = 'smaller')
    prettify(ax)

例如,我不知道为什么法国条在前三年被绘制为粉红色,然后在 1999 年变为绿色,并在接下来的几年中保持不变。

我需要的是每年用相同的条形颜色绘制每个国家/地区。

你能帮我解决这个问题吗?

【问题讨论】:

    标签: python dataframe matplotlib data-visualization bar-chart


    【解决方案1】:

    更正排名系列条形图中的 Y 值

    这里的问题是如何定义和绘制 x 和 y 变量。

    y = s_rank[s_rank >= len(s_rank) - topN]
    
    c1    3.0
    c2    6.0
    c3    2.0
    c4    5.0
    c5    4.0
    c6    1.0
    Name: 1996, dtype: float64
    
    x = s[y.index]
    c1    3168
    c2    6369
    c3    2408
    c4    5441
    c5    5430
    c6    1440
    Name: 1996, dtype: int64
    

    在本例中,矩形的绘制顺序为 c1, c2,...,c6。所以颜色也按该顺序应用。你想要的是按照你的排名顺序绘制。只需对 y 值进行排序即可解决此问题。

    y = s_rank[s_rank >= len(s_rank) - topN].sort_values()
    

    这是一个示例,我设置了 rects[0].set_color('r') 来演示绘图顺序发生了什么。

    以下是该解决方案的实施示例。

    #generate data
    rng = np.random.default_rng(12345)
    idx = ['c1','c2','c3','c4','c5','c6']
    rng = np.random.default_rng()
    exp_data_wide = pd.DataFrame({
        1996: rng.integers(low=500, high=10000, size=6),
        1997: rng.integers(low=500, high=10000, size=6),
        1998: rng.integers(low=500, high=10000, size=6),
        1999: rng.integers(low=500, high=10000, size=6),
        2000: rng.integers(low=500, high=10000, size=6),
        2001: rng.integers(low=500, high=10000, size=6),
    }, index=idx)
    
    #set dates, topN, colors
    dates = [1996, 1997, 1998, 1999, 2000, 2001]
    topN = 5
    colors = ['#aaf542','#5c0794','#ae63e0','#a6a2a8','#97b814','#b86314']
    
    fig, ax_array = plt.subplots(nrows = 1, ncols = 6, figsize = (10, 2.5), dpi = 144, tight_layout = True)
    for ax, date in zip(ax_array, dates):
        #Apply rank
        s = exp_data_wide[date]
        s_rank = s.rank(method = 'first').dropna()
        #define x/y
        y = s_rank[s_rank >= len(s_rank) - topN].sort_values()
        x = s[y.index]
        #plot
        rects = ax.barh (y = y, width = x.values, color=colors, tick_label = x.index)
        ax.set_title(date, fontsize = 'smaller')
        rects[0].set_color('r')
        #style
        [ax.spines[s].set_visible(False) for s in ['top','right','bottom','left']]
        ax.grid(axis='x', dashes=(8,3), alpha=0.3)
        ax.tick_params(axis='both', left=False, bottom=False)
        ax.set_xlim(0,10000)
    

    【讨论】:

    • 非常感谢您回答这个问题!不幸的是,这并没有解决我的问题:我想要实现的是使国家栏颜色在每年中保持不变,即使它改变了位置。就您的示例而言,“c4”应该始终有一个“棕色”颜色条,“c1”一个“红色”一个,“c3”一个“紫色”一个等等......将继续尝试把这个想出来(解决;计算出;弄明白。还是谢谢!
    • 尝试使用字典并在每个 for 循环中使用 y 轴的键进行访问。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-03
    • 2012-01-19
    • 2016-06-03
    • 1970-01-01
    相关资源
    最近更新 更多