Python 如何动态更新循环中的绘图?

Python 如何动态更新循环中的绘图?,python,pandas,matplotlib,Python,Pandas,Matplotlib,我有下面的代码片段,我想扩展它,使每个循环的数据都绘制在同一画布上,而不是将每个循环的数据绘制到不同的画布上 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=

我有下面的代码片段,我想扩展它,使每个循环的数据都绘制在同一画布上,而不是将每个循环的数据绘制到不同的画布上

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')
在最佳情况下,我还希望根据原始数据对散点图中的点进行颜色编码(属于一个循环中的数据的点以相同的颜色着色)


我对matplotlib和pandas都是新手,因此非常感谢andy help。

您可以将整个数据集构建为一个整体,而不是多次调用
plot
DataFrame,然后只需调用
plot
一次

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}]
您可以使用列
level
size
构建数据框架:

df = pd.DataFrame([(level,val) for level, dct in enumerate(result) 
                   for val in dct.values()],
                  columns=['level', 'size'])
看起来是这样的:

    level  size
0       0    21
1       0     7
2       0    67
...
45      1     1
46      1     1
47      1     1
现在我们可以按级别分组,并计算每个
size
组中有多少项:

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
上面返回一个
pd.Series
。要使其成为数据帧,我们可以通过调用
reset\u index()
,将索引级别的值设置为列,然后为列指定列名:

size_count = size_count.reset_index()
size_count.columns = ['level', 'community size', 'number of communities']
现在,可以使用

size_count.plot(kind='scatter', x='community size', y='number of communities', 
                s=100, c='level')
s=100
控制点的大小,
c='level'
告诉
plot
根据
level
列中的值给点上色


如果有几十个级别,使用颜色条可能是合适的


另一方面,如果只有几个关卡,使用图例将使 更有意义。在这种情况下,每次调用
plot
一次更方便 级别值,因为创建图例的matplotlib代码设置为 每个绘图一个图例条目:

import pandas as pd
import matplotlib.pyplot as 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) for level, dct in enumerate(result) 
                   for val in dct.values()],
                  columns=['level', 'size'])
groups = df.groupby(['level'])
fig, ax = plt.subplots()
for 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()

请上传您的样本数据好吗?顺便问一下,is
result
is
dataframe
?如果是这样,for循环倾向于逐行循环,但是
result[level]
实际上尝试访问列
level
。你看不出有任何错误是因为这个引起的吗?嗨@JianxunLi不,结果不是一个数据帧,它是一个字典。我把它的内容上传到这里作为一个例子:这样你就可以复制了。已经是Thx了!非常好@HappyLeapSecond,谢谢。有可能在右边框上有一个图例而不是颜色条吗?@vare:我添加了一些代码,说明如何制作图例而不是颜色条。
import pandas as pd
import matplotlib.pyplot as 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) for level, dct in enumerate(result) 
                   for val in dct.values()],
                  columns=['level', 'size'])
groups = df.groupby(['level'])
fig, ax = plt.subplots()
for 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()