我有以下代码片段,我希望以一种方式扩展,即每个循环的数据在同一画布上绘制,而不是每个循环绘制到不同的循环。
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帮助。
答案 0 :(得分:1)
您可以将整个数据集构建为一个,而不是多次调用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
构建一个DataFrame:
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
上面的groupby/apply
会返回pd.Series
。为了使其成为DataFrame,我们可以通过调用reset_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
列中的值为点着色。
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'])
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()
如果存在数十个级别,则使用颜色栏可能是合适的。
另一方面,如果只有几个级别,则使用图例
更有意义。在这种情况下,为每个人调用plot
一次会更方便
级别值,因为matplotlib代码使得图例设置为make
每个情节一个传奇条目:
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()