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

如何用Python Plotly实现Treemap正负值分色及按日期时间调整

使用Plotly绘制带正负值颜色区分与日期可调的Treemap

解决方案概述

针对你的需求,我们可以通过自定义颜色映射实现负值节点红色、正值节点绿色的样式,同时借助Dash(Plotly的交互框架)实现日期范围的动态筛选,以下是完整的可运行代码和关键细节说明:


1. 数据准备(模拟你的数据结构)

假设你的数据包含日期时间、一级分类、二级分类、百分比变化字段,先模拟一份可复用的测试数据:

import pandas as pd
import numpy as np
from datetime import datetime, timedelta

# 生成模拟数据
dates = pd.date_range(start='2024-01-01', end='2024-01-31', freq='D')
categories = ['产品', '运营', '技术']
sub_categories = ['电商', '线下', '活动', '用户', '后端', '前端']

data = []
for date in dates:
    for cat in categories:
        for sub_cat in sub_categories:
            if sub_cat in ['电商','线下'] and cat == '产品':
                pct = np.random.uniform(-12, 18)
                data.append({
                    'date': date,
                    'category': cat,
                    'sub_category': sub_cat,
                    'percent_change': round(pct, 2)
                })
            elif sub_cat in ['活动','用户'] and cat == '运营':
                pct = np.random.uniform(-8, 22)
                data.append({
                    'date': date,
                    'category': cat,
                    'sub_category': sub_cat,
                    'percent_change': round(pct, 2)
                })
            elif sub_cat in ['后端','前端'] and cat == '技术':
                pct = np.random.uniform(-5, 25)
                data.append({
                    'date': date,
                    'category': cat,
                    'sub_category': sub_cat,
                    'percent_change': round(pct, 2)
                })

df = pd.DataFrame(data)

2. 正负值颜色映射逻辑

直接通过自定义列给每个条目分配颜色,确保负值红、正值绿、零值灰色:

# 自定义颜色规则
df['node_color'] = df['percent_change'].apply(
    lambda x: '#e74c3c' if x < 0 else '#2ecc71' if x > 0 else '#95a5a6'
)

3. 日期动态调整实现

使用Dash的DatePickerRange组件实现日期范围选择,结合回调函数实时更新Treemap:

import plotly.express as px
import dash
from dash import dcc, html, Input, Output, callback

# 初始化Dash应用
app = dash.Dash(__name__)

app.layout = html.Div([
    html.H2("Treemap:按日期筛选+正负值颜色区分"),
    # 日期范围选择器
    dcc.DatePickerRange(
        id='date-selector',
        min_date_allowed=df['date'].min(),
        max_date_allowed=df['date'].max(),
        start_date=df['date'].max() - timedelta(days=6),
        end_date=df['date'].max(),
        display_format='YYYY-MM-DD'
    ),
    # Treemap图表容器
    dcc.Graph(id='treemap-plot')
])

# 回调函数:根据选择的日期更新图表
@callback(
    Output('treemap-plot', 'figure'),
    Input('date-selector', 'start_date'),
    Input('date-selector', 'end_date')
)
def update_treemap(start_date, end_date):
    # 筛选指定日期范围的数据
    filtered_df = df[(df['date'] >= start_date) & (df['date'] <= end_date)]
    # 按分类聚合百分比(可根据你的需求调整聚合逻辑)
    aggregated_df = filtered_df.groupby(['category', 'sub_category'])['percent_change'].sum().reset_index()
    # 重新生成颜色列
    aggregated_df['node_color'] = aggregated_df['percent_change'].apply(
        lambda x: '#e74c3c' if x < 0 else '#2ecc71' if x > 0 else '#95a5a6'
    )
    
    # 绘制Treemap
    fig = px.treemap(
        aggregated_df,
        path=['category', 'sub_category'],
        values=np.abs(aggregated_df['percent_change']),  # 用绝对值确保节点大小不受负值影响
        color='node_color',
        color_discrete_map='identity',  # 直接使用自定义颜色值
        hover_data={
            'percent_change': ':,.2f%',  # 格式化百分比显示
            'node_color': False  # 隐藏颜色字段的hover提示
        },
        title=f"日期范围:{start_date} 至 {end_date}"
    )
    # 显示节点名称和数值
    fig.update_traces(textinfo='label+value')
    return fig

# 运行应用
if __name__ == '__main__':
    app.run_server(debug=True)

关键注意事项

  • 节点大小逻辑:用np.abs()处理百分比,避免负值导致节点大小异常,节点大小反映百分比的绝对值
  • 颜色适配:如果需要调整红绿色调,直接修改#e74c3c(红色)和#2ecc71(绿色)的十六进制颜色码即可
  • 聚合逻辑:根据你的实际数据结构调整groupby的字段,比如如果不需要聚合,直接使用原始筛选数据即可
  • 交互优化:如果不需要Dash的网页交互,也可以用Plotly的静态RangeSlider组件,但动态筛选功能会受限

内容的提问来源于stack exchange,提问作者Đỗ Văn Thắng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 17:35:16