情节:在连续色标中在旭日形中添加大小成比例的子特征 颜色悬停标签

问题描述

这个问题几乎类似于 this one,但有一个重要的区别,即连续色阶,相同的解决方案不适用。

import pandas as pd
import plotly.express as px

data = {
  'ids':['SA','NA','Brazil','Uruguay','USA','Canada','PFV Brazil','PV Brazil','PFV Uruguay','PV Uruguay','PFV USA','PV USA','PFV Canada','PV Canada'],'labels': ['SA','PFV','PV','PV'],'parent': ['','','SA','Canada'],'value': [0,100,80,400,200,8,40,4,20,11,80]
  }

fig =px.sunburst(data,names='labels',parents='parent',values='value',ids='ids',color='value',color_continuous_scale='Blues')
fig.show()

上面的代码重现了这个图-

enter image description here

如您所见,NASA 的颜色是最低端的颜色(因为它们的值为零),但它们与子项的分割比例和大小比例是正确的。

如果我输入他们的值是他们子类的总和,即用 value 替换 'value': [180,600,80],它会产生这个图-

enter image description here

现在,颜色和彼此之间的比例是正确的,但与子类的比例不正确。我怎样才能解决这个问题? (我想要第一个图,但根/父节点的颜色按大小)

解决方法

很明显,如果父类有值,即使子类的总和等于父类,子类也会自动分成不成比例的较小扇区。因此,可能有一个有点理想的解决方案的唯一方法是让父类具有实际值 0,然后手动为它们分配颜色悬停标签 .所以,这是我实施的(几乎荒谬的)解决方法。

颜色

我们的想法是拥有一个非常大的连续色阶,其中包含数百个元素(或更多,取决于您想要的范围)。然后将所需的颜色(我选择了色阶的中点)插入到色阶的起点(最小点)。这样,0 值将具有颜色,并且色阶的极大尺寸将防止所有其他值与它们的原始颜色相差太多。

  1. 您可以从 this 网站生成色阶。我没有看到任何直接导出或复制选项,因此快速复制到 excel 中,然后从中选择所需的列对我来说很有效。

  2. 从中制作一个字符串列表。添加 # 作为每个元素的前缀。

  3. 选择您想要的颜色并将其添加到列表的前面。我选择了中点。

  4. 将列表传递给绘图函数的 colorscale 参数。

# px.colors.sequential.Blues #Get first and last colour from this
my_colorscale = ["F7FBFF","F6FAFE","F5F9FD","F4F8FD","F3F7FC","F2F7FC","F1F6FB","F0F5FA","EFF4FA","EEF3F9","EDF3F9","ECF2F8","EBF1F8","EAF0F7","E9EFF6","E8EFF6","E8EEF5","E7EDF5","E6ECF4","E5EBF3","E4EBF3","E3EAF2","E2E9F2","E1E8F1","E0E7F1","DFE7F0","DEE6EF","DDE5EF","DCE4EE","DBE3EE","DAE3ED","D9E2ED","D9E1EC","D8E0EB","D7DFEB","D6DFEA","D5DEEA","D4DDE9","D3DCE8","D2DBE8","D1DBE7","D0DAE7","CFD9E6","CED8E6","CDD7E5","CCD7E4","CBD6E4","CAD5E3","CAD4E3","C9D3E2","C8D3E1","C7D2E1","C6D1E0","C5D0E0","C4D0DF","C3CFDF","C2CEDE","C1CDDD","C0CCDD","BFCCDC","BECBDC","BDCADB","BCC9DB","BBC8DA","BBC8D9","BAC7D9","B9C6D8","B8C5D8","B7C4D7","B6C4D6","B5C3D6","B4C2D5","B3C1D5","B2C0D4","B1C0D4","B0BFD3","AFBED2","AEBDD2","ADBCD1","ACBCD1","ACBBD0","ABBACF","AAB9CF","A9B8CE","A8B8CE","A7B7CD","A6B6CD","A5B5CC","A4B4CB","A3B4CB","A2B3CA","A1B2CA","A0B1C9","9FB0C9","9EB0C8","9DAFC7","9DAEC7","9CADC6","9BACC6","9AACC5","99ABC4","98AAC4","97A9C3","96A9C3","95A8C2","94A7C2","93A6C1","92A5C0","91A5C0","90A4BF","8FA3BF","8EA2BE","8EA1BD","8DA1BD","8CA0BC","8B9FBC","8A9EBB","899DBB","889DBA","879CB9","869BB9","859AB8","8499B8","8399B7","8298B7","8197B6","8096B5","7F95B5","7F95B4","7E94B4","7D93B3","7C92B2","7B91B2","7A91B1","7990B1","788FB0","778EB0","768DAF","758DAE","748CAE","738BAD","728AAD","7189AC","7089AC","7088AB","6F87AA","6E86AA","6D85A9","6C85A9","6B84A8","6A83A7","6982A7","6881A6","6781A6","6680A5","657FA5","647EA4","637EA3","627DA3","617CA2","617BA2","607AA1","5F7AA0","5E79A0","5D789F","5C779F","5B769E","5A769E","59759D","58749C","57739C","56729B","55729B","54719A","53709A","526F99","526E98","516E98","506D97","4F6C97","4E6B96","4D6A95","4C6A95","4B6994","4A6894","496793","486693","476692","466591","456491","446390","436290","43628F","42618E","41608E","405F8D","3F5E8D","3E5E8C","3D5D8C","3C5C8B","3B5B8A","3A5A8A","395A89","385989","375888","365788","355787","345686","345586","335485","325385","315384","305283","2F5183","2E5082","2D4F82","2C4F81","2B4E81","2A4D80","294C7F","284B7F","274B7E","264A7E","25497D","25487C","24477C","23477B","22467B","21457A","20447A","1F4379","1E4378","1D4278","1C4177","1B4077","1A3F76","193F76","183E75","173D74","163C74","163B73","153B73","143A72","133971","123871","113770","103770","0F366F","0E356F","0D346E","0C336D","0B336D","0A326C","09316C","08306B","08306B"]
midpoint = my_colorscale[int(len(my_colorscale)/2)]
my_colorscale.insert(0,midpoint)
my_colorscale = ['#'+x for x in my_colorscale]

悬停标签

创建一个由每个扇区的值组成的列表,并将该列表传递给函数中的 custom_data 参数。然后,调用 fig.update_traces() 并将 %{customdata} 传递给 hovertemplate 参数。

这是完整的代码-

# px.colors.sequential.Blues #Get first and last colour from this
my_colorscale = ["F7FBFF",midpoint)
my_colorscale = ['#'+x for x in my_colorscale]

value2 = [180,600,100,80,400,200,8,40,4,20,11,80]

import pandas as pd
import plotly.express as px

data = {
  'ids':['SA','NA','Brazil','Uruguay','USA','Canada','PFV Brazil','PV Brazil','PFV Uruguay','PV Uruguay','PFV USA','PV USA','PFV Canada','PV Canada'],'labels': ['SA','PFV','PV','PV'],'parent': ['','','SA','Canada'],'value': [0,80]
  }

fig =px.sunburst(data,names='labels',parents='parent',values='value',ids='ids',color='value',color_continuous_scale=my_colorscale,custom_data=[value2])
fig.update_traces(hovertemplate='%{label}<br>%{customdata}')
fig.show()

这是输出(注意颜色条的底部:D)-

enter image description here

这绝不是完美的解决方案,因为 NASA 的颜色是相同的。我认为这也可以解决,尽管使用足够大的色阶并将其中一个的值更改为 1 而不是 0,因为图形上的眼睛无法理解这种微小的变化,并添加第二个颜色作为列表 my_colorscale 中的第二个元素。

我对更好的解决方案持开放态度,我不会将此标记为答案。