You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Seaborn Barplot条形颜色随IPO股票收益增减加深?

实现IPO股票收益条形图颜色随数值深浅变化的方法

我正在绘制IPO股票的日、周、月收益表现列表,希望条形的颜色随收益数值的增大/减小而加深。以下是我当前使用的代码:

# 我使用的调色板
color_daily = ['red' if x < 0 else 'green' for x in ipo_stocks.sort_values('Daily Return (%)')['Daily Return (%)']]
color_weekly = ['red' if x < 0 else 'green' for x in ipo_stocks.sort_values('Weekly Return (%)')['Weekly Return (%)']]
color_monthly = ['red' if x < 0 else 'green' for x in ipo_stocks.sort_values('Monthly Return (%)')['Monthly Return (%)']]

fig, axes = plt.subplots(3, 1, figsize = (15,15))

fig_1 = sns.barplot(data = ipo_stocks.sort_values('Daily Return (%)'), x = 'Saham', y = 'Daily Return (%)', palette = color_daily, alpha = 0.8, ax = axes[0])
fig_1.set(ylim = (-50,50))
axes[0].tick_params(labelrotation = 90)
axes[0].text(2,40, ('Rata-rata return hari pertama listing: ' + str(round(ipo_stocks['Daily Return (%)'].mean(), 2)) + '%'), fontsize = 15)
axes[0].title.set_text('Performa Daily')

fig_2 = sns.barplot(data = ipo_stocks.sort_values('Weekly Return (%)'), x = 'Saham', y = 'Weekly Return (%)', palette = color_weekly, alpha = 0.8, ax = axes[1])
fig_2.set(ylim = (-100, 300))
axes[1].tick_params(labelrotation = 90)
axes[1].text(2, 250, ('Rata-rata return satu minggu setelah listing: ' + str(round(ipo_stocks['Weekly Return (%)'].mean(), 2)) + '%'), fontsize = 15)
axes[1].title.set_text('Performa Weekly')

fig_3 = sns.barplot(data = ipo_stocks.sort_values('Monthly Return (%)'), x = 'Saham', y = 'Monthly Return (%)', palette = color_monthly, alpha = 0.8, ax = axes[2])
fig_3.set(ylim = (-100, 400))
axes[2].tick_params(labelrotation = 90)
axes[2].text(2, 300, ('Rata-rata return satu bulan setelah listing: ' + str(round(ipo_stocks['Monthly Return (%)'].mean(), 2)) + '%'), fontsize = 15)
axes[2].title.set_text('Performa Monthly')

plt.xticks(rotation = 90)
plt.tight_layout()

当前输出仅能区分正负收益的红绿色,无法实现颜色深浅随收益数值变化,恳请指导实现方法。


解决方案

核心思路

通过颜色映射(Colormap)和数值归一化实现颜色深浅与收益数值挂钩:

  • 正收益:使用绿色系渐变(数值越大,颜色越深)
  • 负收益:使用红色系渐变(数值越小,颜色越深)

修改后的完整代码

import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap, Normalize

# 自定义正负收益的渐变配色
# 红色系:浅红到深红(对应负收益从接近0到最小值)
red_cmap = LinearSegmentedColormap.from_list('red_gradient', ['#ffcccc', '#cc0000'])
# 绿色系:浅绿到深绿(对应正收益从接近0到最大值)
green_cmap = LinearSegmentedColormap.from_list('green_gradient', ['#ccffcc', '#009900'])

def get_gradient_colors(values):
    """根据收益值生成渐变颜色列表"""
    colors = []
    # 分别处理正负值的归一化范围
    pos_values = values[values >= 0]
    neg_values = values[values < 0]
    
    # 正收益归一化
    if len(pos_values) > 0:
        norm_pos = Normalize(vmin=0, vmax=pos_values.max())
    # 负收益归一化(取绝对值)
    if len(neg_values) > 0:
        norm_neg = Normalize(vmin=neg_values.min(), vmax=0)
    
    for val in values:
        if val >= 0:
            colors.append(green_cmap(norm_pos(val)) if len(pos_values) > 0 else '#ccffcc')
        else:
            colors.append(red_cmap(norm_neg(val)) if len(neg_values) > 0 else '#ffcccc')
    return colors

# 按收益排序数据,并生成对应渐变颜色
daily_sorted = ipo_stocks.sort_values('Daily Return (%)')
color_daily = get_gradient_colors(daily_sorted['Daily Return (%)'])

weekly_sorted = ipo_stocks.sort_values('Weekly Return (%)')
color_weekly = get_gradient_colors(weekly_sorted['Weekly Return (%)'])

monthly_sorted = ipo_stocks.sort_values('Monthly Return (%)')
color_monthly = get_gradient_colors(monthly_sorted['Monthly Return (%)'])

# 绘制子图,保留原逻辑仅替换调色板
fig, axes = plt.subplots(3, 1, figsize=(15,15))

fig_1 = sns.barplot(data=daily_sorted, x='Saham', y='Daily Return (%)', palette=color_daily, ax=axes[0])
fig_1.set(ylim=(-50,50))
axes[0].tick_params(labelrotation=90)
axes[0].text(2,40, f'Rata-rata return hari pertama listing: {round(ipo_stocks["Daily Return (%)"].mean(), 2)}%', fontsize=15)
axes[0].title.set_text('Performa Daily')

fig_2 = sns.barplot(data=weekly_sorted, x='Saham', y='Weekly Return (%)', palette=color_weekly, ax=axes[1])
fig_2.set(ylim=(-100, 300))
axes[1].tick_params(labelrotation=90)
axes[1].text(2, 250, f'Rata-rata return satu minggu setelah listing: {round(ipo_stocks["Weekly Return (%)"].mean(), 2)}%', fontsize=15)
axes[1].title.set_text('Performa Weekly')

fig_3 = sns.barplot(data=monthly_sorted, x='Saham', y='Monthly Return (%)', palette=color_monthly, ax=axes[2])
fig_3.set(ylim=(-100, 400))
axes[2].tick_params(labelrotation=90)
axes[2].text(2, 300, f'Rata-rata return satu bulan setelah listing: {round(ipo_stocks["Monthly Return (%)"].mean(), 2)}%', fontsize=15)
axes[2].title.set_text('Performa Monthly')

plt.xticks(rotation=90)
plt.tight_layout()
plt.show()

关键说明

  1. 自定义渐变配色:通过LinearSegmentedColormap创建从浅到深的红、绿渐变,可直接修改十六进制颜色值调整过渡效果。
  2. 数值归一化:Normalize将收益值映射到[0,1]区间,确保颜色渐变幅度与数值大小成正比。
  3. 颜色生成逻辑:get_gradient_colors函数分别处理正负收益,保证正收益随数值增大颜色加深,负收益随数值减小(更负)颜色加深。
  4. 代码优化:改用f-string简化字符串拼接,提升代码可读性。

内容的提问来源于stack exchange,提问作者Winston Mulyawan Setiabudi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 00:09:57