How to make condition in treemap with red as negative value and green as positive value?

Here is my code, I don’t know how to make the positive value green , seems in my code the result is wrong

data = pd.DataFrame(
    {
        "Timestamp":['14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022',
        '14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022',
        '14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022',
        '14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022','14-02-2022',
        '14-02-2022','14-02-2022','14-02-2022','14-02-2022'],
        "Name":['Binance','OKX','Kucoin','Houbi','FTX','Bitfinex','Bitmex','Bittrex','CoinList','BNB_US','MEXC','Crypto','Gate','Bitstamp','FTX_US','Coinbase',
        'Binance','OKX','Kucoin','Houbi','FTX','Bitfinex','Bitmex','Bittrex','CoinList','BNB_US','MEXC','Crypto','Gate','Bitstamp','FTX_US','Coinbase',
        'Binance','OKX','Kucoin','Houbi','FTX','Bitfinex','Bitmex','Bittrex','CoinList','BNB_US','MEXC','Crypto','Gate','Bitstamp','FTX_US','Coinbase'],

        "Stablecoin":['USDT','USDT','USDT','USDT','USDT','USDT','USDT','USDT','USDT','USDT','USDT','USDT','USDT','USDT','USDT','USDT',
        'USDC','USDC','USDC','USDC','USDC','USDC','USDC','USDC','USDC','USDC','USDC','USDC','USDC','USDC','USDC','USDC',
        'BUSD','BUSD','BUSD','BUSD','BUSD','BUSD','BUSD','BUSD','BUSD','BUSD','BUSD','BUSD','BUSD','BUSD','BUSD','BUSD'],

        "Value_USDT":[7.44,6.54,5.45,3,2,1.45,3,2,1,3,2,1,1,2,1,2,
        7,6,5,3,2,1,3,2,1,3,2,1,1,2,1,2,
        10.08,0,5,0,7,0,0,0,0,3,2,1,4,0,0,2],
        'percentage':[7.87,6.78,-5.08,-0.9,2.87,1.87,-3.78,2.87,1.6,3.67,-2.4,1.43,1.34,2.23,1.34,2.43,
        7.78,6.43,5.43,3.45,2,1,3,2,-1.98,3,2,-1.76,1,2,1,2,
        10.08,0.09,-5,0.07,7,0.76,0.67,0.87,0.56,-3,2,-1.65,4,0.56,0.65,2]
    }
)
data['all'] = 'all'
def set_colorscale(z, colors):
    if len(colors) !=3:
        raise ValueError("")
    neg=z[np.where(z<0)]
    pos=z[np.where(z>0)]    
    a, c = neg.min(), neg.max()
    d, b = pos.min(), pos.max()
    bvals= [a, c/2, d/2, b]
    nvals = [(v-bvals[0])/(bvals[-1]-bvals[0]) for v in bvals] 
    dcolorscale = []
    for k in range(len(colors)):
        dcolorscale.extend([[nvals[k], colors[k]], [nvals[k+1], colors[k]]])
    return dcolorscale  

z = np.array(data['percentage'])
pl_colorscale= set_colorscale(z, ["#DC3714", "#C0C0C0", "#19BD1B"])
fig = px.treemap(data, path=[px.Constant('all'),'Stablecoin','Name','percentage'],values='Value_USDT')
fig.update_traces(textinfo = "label",textposition="middle center",hovertemplate='labels=%{label}<br>value=%{value}<extra></extra>')
fig.update_traces(hovertext=['percentage'])
fig.update_traces(marker=dict(
    colors=data['percentage'],
    colorscale=pl_colorscale,
    showscale=True
))
fig.update_layout(width=1400, height=550,title="TreeMap stablecoin")
fig.show()

this is my result:

Hi @StevenDO and welcome to the forum,

could you please format your code like this:

I have seen you use if-then statements so the indentation is important to know.

I just edit it

@StevenDO
This is the working code, and its explanation:

data["all"]="all"
fig = px.treemap(data, path=[px.Constant('all'),'Stablecoin','Name','percentage'], 
                 values='Value_USDT')
my_colorway=("#636efa", "#e763fa", "#ab63fa")   
fig.update_layout(treemapcolorway=my_colorway,  
           width=1000, height=450, title_text="TreeMap stablecoin", title_x=0.5)
leafs = fig.data[0].labels[:len(data["percentage"])]
leafs = [float(leaf) for leaf in leafs]
mycolors = ["#DC3714" if leafv < 0 else "#19BD1B" for leafv in leafs]
newlabels= [f"{fig.data[0].labels[k]}%" if k < len(data["percentage"]) else fig.data[0].labels[k] 
            for k in range(len(fig.data[0].labels))]
fig.update_traces(labels=newlabels)
fig.update_traces(marker_colors=mycolors, root_color="#c0c0c0")
fig.show()


The data of a fig returned by px.treemap and px.sunburst must be updated carefully, because fig.data[0] contains
a tree data structure with a real root or with a fake root, like in your example, where the fake root is "all".
This tree is recorded from leafs to the (pseudo)root:

fig.data[0].labels

array(['-5.08', '-5.0', '-3.78', '-3.0', '-2.4', '-1.98', '-1.76',
       '-1.65', '-0.9', '0.07', '0.09', '0.56', '0.56', '0.65', '0.67',
       '0.76', '0.87', '1.0', '1.0', '1.0', '1.34', '1.34', '1.43', '1.6',
       '1.87', '2.0', '2.0', '2.0', '2.0', '2.0', '2.0', '2.0', '2.23',
       '2.43', '2.87', '2.87', '3.0', '3.0', '3.45', '3.67', '4.0',
       '5.43', '6.43', '6.78', '7.0', '7.78', '7.87', '10.08', 'BNB_US',
       'BNB_US', 'BNB_US', 'Binance', 'Binance', 'Binance', 'Bitfinex',
       'Bitfinex', 'Bitfinex', 'Bitmex', 'Bitmex', 'Bitmex', 'Bitstamp',
       'Bitstamp', 'Bitstamp', 'Bittrex', 'Bittrex', 'Bittrex',
       'CoinList', 'CoinList', 'CoinList', 'Coinbase', 'Coinbase',
       'Coinbase', 'Crypto', 'Crypto', 'Crypto', 'FTX', 'FTX', 'FTX',
       'FTX_US', 'FTX_US', 'FTX_US', 'Gate', 'Gate', 'Gate', 'Houbi',
       'Houbi', 'Houbi', 'Kucoin', 'Kucoin', 'Kucoin', 'MEXC', 'MEXC',
       'MEXC', 'OKX', 'OKX', 'OKX', 'BUSD', 'USDC', 'USDT', 'all'],
      dtype=object)

Notice that the first 48 values are the permuted values of the column data["percentage"].
That’s why I defined marker_colors according to the sign
of the first 48 labels, converted to floats.
I also concatenated the symbol % to each string in fig.data[0].labels[:48].
Since the default plotly colorway contains red for the third subtree, and a red background and red negative percents are not sufficiently informative, I changed the colorway, i.e. the colors of the first three
subtrees (you can change my_colorway with your prefered colors).

Ohh i have fix it before, But thank you very much the code is

data['all'] = 'all'
condition = [data['percentage']>0,
            data['percentage']==0,
            data['percentage']<0]

choices = ['A','B','C']
data['Condition'] = np.select(condition,choices,default='D')

fig = px.treemap(data, path=[px.Constant('all'),'Stablecoin','Name','percentage'],
                 values='Value_USDT',color='Condition',
                 color_discrete_map={'(?)':'black','A':"#19BD1B", 
                                     'B':"#C0C0C0",
                                     'C':"#DC3714",
                                     'D':'#AB63FA'})
fig.update_traces(textinfo = "label",
                  textposition="middle center",
                  hovertemplate='labels=%{label}<br>value=$%{value}<extra></extra>',
                  texttemplate='%{label: labels }% <br> $%{value: 0.2s}')
fig.update_traces(hovertext=['percentage'])
fig.update_layout(width=1400, height=550,title="TreeMap stablecoin",paper_bgcolor='rgba(225,225,225,225)',title_font_size=20)
fig.data[0]['textfont']['size'] = 14
fig.show()

Alternatively could you have done:

fig2 = px.treemap(
    data[data.Value_USDT != 0],
    path=[px.Constant("all"), "Stablecoin", "Name"],
    values="Value_USDT",
    color="percentage",
    color_continuous_scale=px.colors.diverging.RdBu,  # https://plotly.com/python/builtin-colorscales/#builtin-diverging-color-scales
    color_continuous_midpoint=0,
)
fig2.show()

If yes, could you let me know how I can change the colorscale afterward? It seems fig2.update_traces( ) doesn’t have any effect?

fig2.update_traces(marker_colorscale="Greens", selector=lambda x: True, overwrite=True)

I still get the same colors as before …