Не уверен, поймал ли я все возможные варианты, но вот моя обновленная попытка, которая собирает все возможные комбинации.
Если вы хотите иметь больше пробелов между метками, вам нужно либо увеличить figsize
, либо уменьшить fontsize
(или решить, когда и как «разбить» непрерывную «числовую линию» вдоль x).
Результат:
Код:
import itertools
import matplotlib.pyplot as plt
import matplotlib as mpl
input_dict= {'l': 12, 'b': 20, 'k':1, 'a':10, 'd':30 }
combinations=[]
## set the length of calculated combinations here:
for lengths in range(1,len(input_dict)):
perm_length=lengths
combinations += list(map( dict, itertools.combinations( input_dict.items(), perm_length ) ) )
sum_dict={}
for d in combinations:
s=sorted(d,key=d.get,reverse=True)
sum_dict[sum(d.values())]=list(s)
ordered_dict={x:sum_dict[x] for x in sorted(sum_dict, reverse=True )}
## plotting
fig,ax=plt.subplots(figsize=(10,5))
arrow_props = dict(fc='k', ec='k',
headlength=10, headwidth=3,
width=.5,shrink=0.15,zorder=2)
## make some nice colors:
cmap = mpl.cm.get_cmap('nipy_spectral')
norm=mpl.colors.Normalize(vmin=0,vmax=len(ordered_dict))
for i,a_sum in enumerate(ordered_dict.items()):
### iterate over the "addends", plot them at y=1:
for ie,elem in enumerate(a_sum[1]):
perm_length=len(a_sum[1])
_txt='{0} ({1})'.format( elem, input_dict[elem])
## I create a ax.text() and ax.annotate() separately,
# in order to have more granular control of the appearance
_offset=-(perm_length-1)/(2*perm_length)
ax.text(i + ie/perm_length +_offset , 1 , _txt,
ha="center",va="bottom",rotation=90, fontsize=8,
bbox=dict(facecolor=cmap(norm(i)), alpha=0.5))
ax.annotate("", xy=(i,0), xytext=(i + ie/perm_length +_offset, 1 ),
ha='center',arrowprops=arrow_props)
## plot the sum at y=0
ax.text(i,0,a_sum[0],
ha="center",va="center",rotation=90, fontsize=8,
bbox=dict(facecolor=cmap(norm(i)), alpha=0.5))
ax.set_xlim(-1,len(ordered_dict)+1)
ax.set_ylim(-1,2)
plt.tight_layout()
plt.show()