python - How to dynamically update a plot in a loop? -


i have following snippet extend in way data each loop gets plotted on same canvas instead of each loop different one.

for level in range(len(result)):   sizes = result[level].values()   distribution=pd.dataframe(counter(sizes).items(), columns=['community size','number of communities'])   distribution.plot(kind='scatter', x='community size', y='number of communities') 

in optimal case additionally have dots in scatterplot color-coded according original data (dots belonging data 1 loop colored in same color).

i more or less new both matplotlib , pandas, andy highly appreciated.

instead of calling plot many times, build entire data set 1 dataframe , need call plot once.

starting

result = [{0: 21, 1: 7, 2: 67, 3: 12, 4: 15, 5: 7, 6: 54, 7: 49, 8: 50, 9: 31,            10: 6, 11: 2, 12: 8, 13: 2, 14: 2, 15: 1, 16: 35, 17: 2, 18: 1, 19:            4, 20: 2, 21: 4, 22: 3, 23: 1, 24: 1, 25: 1, 26: 1, 27: 1, 28: 1,             29: 1},            {0: 2, 1: 5, 2: 2, 3: 3, 4: 1, 5: 2, 6: 3, 7: 2, 8: 1, 9: 1, 10: 1,            11: 1, 12: 1, 13: 1, 14: 1, 15: 1, 16: 1, 17: 1}] 

you build dataframe columns level , size:

df = pd.dataframe([(level,val) level, dct in enumerate(result)                     val in dct.values()],                   columns=['level', 'size']) 

which looks this:

    level  size 0       0    21 1       0     7 2       0    67 ... 45      1     1 46      1     1 47      1     1 

now can group level, , count how many items of each size there in each group:

size_count = df.groupby(['level'])['size'].apply(lambda x: x.value_counts()) # level     # 0      1      9 #        2      5 #        7      2 # ... # 1      1     11 #        2      4 #        3      2 #        5      1 # dtype: int64 

the groupby/apply above returns pd.series. make dataframe, can make index level values columns calling reset_index(), , assign column names columns:

size_count = size_count.reset_index() size_count.columns = ['level', 'community size', 'number of communities'] 

now desired plot can generated with

size_count.plot(kind='scatter', x='community size', y='number of communities',                  s=100, c='level') 

s=100 controls size of dots, c='level' tells plot color dots according value in level column.


import pandas pd import matplotlib.pyplot plt  result = [{0: 21, 1: 7, 2: 67, 3: 12, 4: 15, 5: 7, 6: 54, 7: 49, 8: 50, 9: 31,            10: 6, 11: 2, 12: 8, 13: 2, 14: 2, 15: 1, 16: 35, 17: 2, 18: 1, 19:            4, 20: 2, 21: 4, 22: 3, 23: 1, 24: 1, 25: 1, 26: 1, 27: 1, 28: 1,             29: 1},            {0: 2, 1: 5, 2: 2, 3: 3, 4: 1, 5: 2, 6: 3, 7: 2, 8: 1, 9: 1, 10: 1,            11: 1, 12: 1, 13: 1, 14: 1, 15: 1, 16: 1, 17: 1}]  df = pd.dataframe([(level,val) level, dct in enumerate(result)                     val in dct.values()],                   columns=['level', 'size']) size_count = df.groupby(['level'])['size'].apply(lambda x: x.value_counts()) size_count = size_count.reset_index() size_count.columns = ['level', 'community size', 'number of communities'] cmap = plt.get_cmap('jet') size_count.plot(kind='scatter', x='community size', y='number of communities',                  s=100, c='level', cmap=cmap) plt.show() 

enter image description here

using colorbar might appropriate if there dozens of levels.


on other hand, if there few levels, using legend make more sense. in case, more convenient call plot once each level value, since matplotlib code makes legend set make 1 legend entry per plot:

import pandas pd import matplotlib.pyplot plt  result = [{0: 21, 1: 7, 2: 67, 3: 12, 4: 15, 5: 7, 6: 54, 7: 49, 8: 50, 9: 31,            10: 6, 11: 2, 12: 8, 13: 2, 14: 2, 15: 1, 16: 35, 17: 2, 18: 1, 19:            4, 20: 2, 21: 4, 22: 3, 23: 1, 24: 1, 25: 1, 26: 1, 27: 1, 28: 1,             29: 1},            {0: 2, 1: 5, 2: 2, 3: 3, 4: 1, 5: 2, 6: 3, 7: 2, 8: 1, 9: 1, 10: 1,            11: 1, 12: 1, 13: 1, 14: 1, 15: 1, 16: 1, 17: 1}]  df = pd.dataframe([(level,val) level, dct in enumerate(result)                     val in dct.values()],                   columns=['level', 'size']) groups = df.groupby(['level']) fig, ax = plt.subplots() level, grp in groups:     size_count = grp['size'].value_counts()     ax.plot(size_count.index, size_count, markersize=12, marker='o',              linestyle='', label='level {}'.format(level)) ax.legend(loc='best', numpoints=1) ax.set_xlabel('community size') ax.set_ylabel('number of communities') ax.grid(true) plt.show() 

enter image description here


Comments

Popular posts from this blog

searchKeyword not working in AngularJS filter -

sequelize.js - Sequelize: sort by enum cases -

user interface - how to replace an ongoing process of image capture from another process call over the same ImageLabel in python's GUI TKinter -