Нарисуйте схему суммирования чисел из словаря - PullRequest
0 голосов
/ 19 мая 2019

С учетом словаря, как показано ниже,

dict1 = {l: 12, b: 20, k:1, a:10, d:30 }

Требуются графики, которые представляют сумму каждой возможной комбинации чисел в словаре.Представление диаграммы одной возможной комбинации было бы как ниже.

enter image description here

Комбинации упорядочены в порядке убывания суммы.Внутри этой комбинации элемент отображается в порядке убывания значения.

Мне нужна помощь для этого в записной книжке Jupyter с matplotlib или seaborn или аналогичными библиотеками.

1 Ответ

3 голосов
/ 22 мая 2019

Не уверен, поймал ли я все возможные варианты, но вот моя обновленная попытка, которая собирает все возможные комбинации. Если вы хотите иметь больше пробелов между метками, вам нужно либо увеличить figsize, либо уменьшить fontsize (или решить, когда и как «разбить» непрерывную «числовую линию» вдоль x).

Результат:

A flowchart-like number line in matplotlib

Код:

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()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...