虽然其他人不太可能需要编写类似这样的代码,但由于我已经找到了解决方案并且我不想让这个问题悬而未决,但我将尝试解释我的解决方案。任何好奇的人都可以继续阅读......
我通过创建两个空列表来解决这个问题 - 一个用于“超集”内部切片,一个用于“子集”外部切片,然后在图表数据迭代时填充它们。尽管子集切片始终是原始图表数据结构中超集切片的子代,但无需保留该结构即可呈现图表。
没有子集的超集被添加到超级和子列表中,但这在最终的饼图中是不可见的。要理解“不可见”的含义,想象模型图像中的蓝色切片实际上是由一个内段和外段组成,一个在另一个旁边。如果饼图展开并布置成两条平行的直线轨道,它们仍然会相互对齐,因为它们具有相同的百分比。
但应该只标记一个,并且在外部区域有更多的文本空间。因此,不包含子集切片的超集切片会删除其名称标签并设置为数据类型None。这些名称标签被移动到每个相邻的子集切片。标记为None 的切片将不会被渲染,但位置标记将旋转该切片的百分比。以模型图像为例,这允许从绿色超集切片的末端移动到橙色超集切片的开头,而不会在蓝色切片“上方”绘制不需要的第二个切片。 (将内部超集切片想象成覆盖在外部子集切片之上。)
大多数阅读本文的人可能都知道,将None 数据类型作为字典中的键不会多次起作用。例如,条目"Platypus" : 14.2 将导致None : 14.2,这将被"Jabberwock" : 41.6 覆盖为None : 41.6。因此,我决定先将字典 chart_data 转换为列表,然后再将其格式化为图表。
随着迭代的发生,子集切片的百分比得到统计,以便它们的父超集组在大小上匹配它们。 (大小意味着宽度如果布置在两条平行轨道上,旋转角度如果在饼图中查看。)
最后,我输入了一些代码来检查图表百分比加起来是否为 100。
chart_data = {
"Mammal Group": [{"Hamster":23.1}, {"Yeti":16.4}],
"Platypus": 14.2,
"Reptile Group": [{"Snake":4.0}, {"Komodo Dragon":0.7}],
"Jabberwock" : 41.6
}
track_sup = []
track_sub = []
def dict_to_list(dict): # converts a dictionary to a list (nested dictionaries are untouched)
new_list = []
for key, value in dict.items():
super_pair = [key, value]
new_list.append(super_pair)
return new_list
def format_data(dict_data):
global track_sup
global track_sub
track_sup = []
track_sub = []
print('\n\n\n====== Formatting data ======')
super_slices = dict_to_list(dict_data) # convert to list to allow more than one single super slice (their labels are type: None)
chart_perc = 0.0 # for checking that the chart slices all add up to 100%
i = 0
while i < len(super_slices):
tally = 0.0 # for adding up subset percentages to get each superset percentage
is_single = True # supersets single by default
super_slice = super_slices[i]
slice_label = ''
super_pair = []
sub_pair = []
if type(super_slice[1]) == list: # if [1] is a list, there are sub slices
is_single = False # mark superset as containing multiple subsets
slice_label = super_slice[0]
sub_slices = super_slice[1]
j = 0
while j < len(sub_slices): # iterate sub slices to gather label names and percentages
sub_slice = sub_slices[j]
for k, v in sub_slice.items(): # in each dict, k is a label and v is a percentage
v = float(v)
tally = tally + v # count toward super slice (group) percentage
chart_perc = chart_perc + v # count toward chart total percentage
sub_pair = [k, v] # convert each key-value pair into a list
print(str(sub_pair[0]) + ' ' + str(sub_pair[1]) + ' %')
track_sub.append(sub_pair) # append this pair to final sub output list
j = j + 1
print('Group [' + slice_label + '] combined total is ' + str(tally) + ' % \n')
elif type(super_slice[1]) == float: # this super slice (group) contains no sub slices
slice_label = super_slice[0]
tally = super_slice[1] # no sub slice percentages to add up
chart_perc = chart_perc + super_slice[1] # count toward chart total percentage
sub_pair = [slice_label, tally] # label drops to the sub slot as it only labels itself
track_sub.append(sub_pair) # append this pair to final sub output list
print(slice_label + ' ' + str(tally) + ' % (Does not belong to a group)\n')
else:
print('Error: Could not format data.')
if is_single == True:
slice_label = None # label removed for each single slice - only the percentage is used (for spacing)
super_pair = [slice_label, tally] # pair up each label name and super slice percentage in a list
track_sup.append(super_pair) # append this pair to final super output list
i = i + 1
chart_perc = round(chart_perc, 6) # round to 6 decimal places
short = 0.0
if chart_perc == 100.0:
print('______ Sum of all chart slices is 100 % ______\n')
else:
print('****** WARNING: Chart slices do not add up to 100 % ! ******')
short = round(100.0 - chart_perc, 6)
print('Sum of all chart slices is only ' + str(chart_perc) + ' % (Falling short by ' + str(short) + ' %)\n')
format_data(chart_data)
print(track_sup)
print(track_sub)
以及由此产生的控制台输出:
====== Formatting data ======
Hamster 23.1 %
Yeti 16.4 %
Group [Mammal Group] combined total is 39.5 %
Platypus 14.2 % (Does not belong to a group)
Snake 4.0 %
Komodo Dragon 0.7 %
Group [Reptile Group] combined total is 4.7 %
Jabberwock 41.6 % (Does not belong to a group)
______ Sum of all chart slices is 100 % ______
[['Mammal Group', 39.5], [None, 14.2], ['Reptile Group', 4.7], [None, 41.6]]
[['Hamster', 23.1], ['Yeti', 16.4], ['Platypus', 14.2], ['Snake', 4.0], ['Komodo Dragon', 0.7], ['Jabberwock', 41.6]]
track_sup 和 track_sub 是两个列表,其数据显示在最后两行输出中,实际用于渲染图表。