目录

问题描述

问题拆解

数据准备

绘图思路

代码实现

总结

成图

network 性质

参考


问题描述

专业描述:想要绘制一幅社交网络图,并且每个节点上绘制一个饼状图。

大白话:韩韩(楼主)有一天突发奇想,想要画一张图,可以一目了然的展现好友关系以及不同好友的各项兴趣爱好。

问题拆解

数据准备

原始CSV数据下载链接:

链接:https://pan.baidu.com/s/1LuNH-6YDsoyGqqJL2JbKYA 
提取码:7as7

好友名单以及兴趣爱好表(表名为:friend_node.csv)。

这里的source就是代表楼主和楼主的朋友们,node_label表示楼主及朋友们的名称。node_size表示楼主和朋友们的相对身高或者balabalaa,任意代表个人属性的性质。share1-shre4表示楼主及朋友们在摄影、游泳、做饭、瑜伽这四项兴趣爱好的相对时间分布情况,这四项相加为100。

楼主与好友的关系表。(表名为:friend_edge.csv)

这里的source和target分别表示楼主和朋友们,比如(1,2)就表示楼主和LL是好朋友。

绘图思路

用Gephi其实可以做出漂亮的network图,但是楼主还需要在每个node上添加代表不同朋友的兴趣的属性,Gephi暂时还实现不了。就转战python。

绘制思路其实分为如下几步:

  • 提取数据,用python从CSV文件中提取node和edge的数据。现实分析问题时,大都需要处理大量的数据,所以楼主附上此步的code,对python小白来说非常友好。(此处需点赞!!!)
  • 选取绘制网络图的package,python中有多个package均可实现绘制网络图,如NetworkX、PyVis、Visdcc in Dash。(详细请阅读:https://towardsdatascience.com/visualizing-networks-in-python-d70f4cbeb259)。楼主选取的是networkX包,(这可能就是第一眼就喜欢上的package,呸,瞎说,第一眼搜到的package)。这个包可以整体绘制网络图、也可以将node,edge分次绘制。就类似ps的图层概念,一层一层画,叠加起来,顺着这个思路,要实现目的,就可以先绘制出edge,然后在每个node的位置绘制上pie图。之后再补充细节,如添加node的label等。

代码实现


# -*- coding: utf-8 -*-
"""
Created on Sun Jun 20 23:21:27 2021@author: HJ
"""
##############################################################################
import csv
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt##############################################################################
################################# 数据提取 ####################################
##############################################################################
######读取node的表头
with open('friend_node.csv', 'r', encoding='UTF-8') as nodecsv: # Open the filereader=csv.reader(nodecsv)header_row=next(reader)
for index,column_header in enumerate(header_row):print(index,column_header)######提取node表
with open('friend_node.csv', 'r', encoding='UTF-8') as nodecsv: # Open the filenodereader = csv.reader(nodecsv) # Read the csv 不读表头nodes = [n for n in nodereader][1:]
print(nodes)
node_names  = [n[0] for n in nodes]###定义node的weight
node_weight = [n[2] for n in nodes]#由于这样定义的node weigt是文本格式,所以将文本转化为数值
node_weight = np.array(node_weight)
print("node weight", node_weight)
node_weight_float = [ float(x) for x in node_weight ]
max_node_weight = max(node_weight_float)
min_node_weight = min(node_weight_float)#定义node 的label
node_label = [n[1] for n in nodes]#将node的属性以字典的形式储存
temp_attrs = [n[3:7] for n in nodes] #这里储存的信息是为了画pie图
attrs = dict(zip(node_names,temp_attrs)) #组成字典
print(attrs)######读取edge表
with open('friend_edge.csv', 'r', encoding='UTF-8') as edgecsv: # Open the fileedgereader = csv.reader(edgecsv) # Read the csvedges_all = [tuple(e) for e in edgereader][1:] # Retrieve the data
print(edges_all)
edges = [i[0:2][::-1] for i in edges_all] #提取前两列的数据
print(edges)##############################################################################
################################# 绘制network ################################
##############################################################################
######设置画布大小,数值越大,后面画的像素越高、越清晰
plt.figure(4,figsize=(50,40))
###### make graph
G = nx.DiGraph() #这里一定要选择有向图,后面才可以画出curve
G.add_nodes_from(node_names,weight = node_weight )  #添加节点
G.add_edges_from(edges) #添加边#######确定布局方式
pos = nx.spring_layout(G,k=1/3.3,scale=6,seed = 10,weight='weight')
'''
参数解释:
#k值决定了节点之间的距离,默认的设定是1/sqrt(n),n是节点数量。一般情况下,当k<1时,节点多集中在圆心内; 当k>1时,节点向圆周分布
#scale值会同比例的放大或者缩小节点的相对位置,scale<1,画面越挤;scale>1,画面越分散。
#seed,固定初始的随机数的位置,若不固定,每次画出的图布局都不一样,原理是spring_layout这种布局算法会初始先随机找一个点,然后通过不断的迭代对点的位置进行优化。
'''
######显示网络图的基本属性
density = nx.density(G)
print("Network density:", density)######绘制节点的label
node_labels = dict(zip(G.nodes,node_label))
nx.draw_networkx_labels(G, pos=pos, labels = node_labels, font_size=50,alpha=0.98 )
'''
这里font_size决定了node label 的大小
alpha 的大小决定了label的透明度
'''
######绘制edge
nx.draw_networkx_edges(G,edge_color='gray', arrowsize = 5,  width=0.8, pos=pos, connectionstyle='arc3,rad=0.2')#在这里添加属性,添加颜色和大小
print(nx.info(G))
'''
arrowsize表示有向图里边的箭头的大小
connectionstyle='arc3,rad=0.2':其实设置的边的弧度,绘制出曲线,默认是直线
'''
######绘制pie图
#设置pie图里每个扇形的颜色
colors = ['orangered', 'dodgerblue', 'gold',  'darkseagreen']
#设置pie图的legend的label
labels1 = [u'Photography',u'Swimming',u'Cooking',u'Yoga'] #定义标签b = -1
for node in G.nodes:attributes = attrs[node]attribute_float = list(map(lambda x:float(x), attributes))b = b + 1current_radius = (node_weight_float[b] - min_node_weight)*0.5/(max_node_weight-min_node_weight) + 0.2'''node的weight,这里设置一个线性函数,调整node size的相对大小,并将该数值赋值给pie图的半径'''a = plt.pie(attribute_float, # center=pos[node],  #pie图的位置就是node的位置labels=labels1, #给pie图添加label,由于所有pie图的label是一致的,所以只需绘制一次legend即可colors = colors ,pctdistance = 0.6,textprops = { 'fontsize':0}, #set label fontsize to zero so it won't showradius=current_radius, #调整pie图的半径wedgeprops={'alpha':0.9}) #调整透明度if b == 0: # only draw legend onceplt.legend(loc='upper right', prop={'size': 50}) ###设置坐标轴
'''
坐标轴的大小一定要和网络图匹配,否则会导致一些node,edge或者node label 显示不出来
'''
plt.ylim(-9.5,8)
plt.xlim(-9,11)###保存图片
plt.savefig('friend.png') #一定放在plt.show()之前
plt.show()

总结

成图

最终的图片是不是超美!!!不接受反驳~

network 性质

以下是该网络的一些基本性质,如节点个数是10个,共有50条边,平均入度是5,出度也是5。

print(nx.info(G))
Name: 
Type: DiGraph
Number of nodes: 10
Number of edges: 50
Average in degree:   5.0000
Average out degree:   5.0000

参考

以下代码参考链接:(楼主为了绘制此图,搜索了n多链接,累的快要吐血,最终筛选如下有用的几个链接)

  • networkX包的官方说明文件,请务必详读!!!https://networkx.org/documentation/stable/reference/generated/networkx.drawing.layout.spring_layout.html;
  • 绘制pie图的参考文件 :https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.legend.html
  • 一些其他参考:https://blog.csdn.net/u012111465/article/details/72797032

原创不易,觉得有用请点赞收藏转发。多谢!!!

完结,撒花~

Python绘制节点是饼状图的社交网络图(Plot network with pie chart)相关推荐

  1. 最全Python绘制饼形图(饼状图)

    饼状图(pie chart)一般用于描述分类型数据的相对频数或百分数频数分布,呈现部分与总体的关系.    一.导入绘图数据 首先导入绘图所需的数据. import os import pandas ...

  2. Matplotlib绘制漂亮的饼状图|python绘制漂亮的饼状图

    python绘图系列文章目录 往期python绘图合集: python绘制简单的折线图 python读取excel中数据并绘制多子图多组图在一张画布上 python绘制带误差棒的柱状图 python绘 ...

  3. C#绘制立体三维饼状图(超酷)

    原文地址: http://www.msproject.cn/Article/3DTransparentPie.html [翻译]Julijan Sribar著3D Pie Chart 一个用于绘制立体 ...

  4. Python数据可视化:饼状图

    使用python实现论文里面的饼状图: 原图: python代码实现: # # 饼状图# plot.figure(figsize=(8,8))labels = [u'Canteen', u'Super ...

  5. 用python把数据画成饼状图_Python学习第92课——数据可视化之饼状图绘制

    [每天几分钟,从零入门python编程的世界!] 假如一个行业只有ABCD四个公司,我们想要用图表展现,它们各自每年的生产总额,占整个行业的比例是多少,这时我们用饼状图(pie chart)更好. 假 ...

  6. 【H5】 echarts绘制条形统计图,饼状图

    [H5] echarts绘制条形统计图 表格需要引入echarts.js: https://echarts.baidu.com/dist/echarts.min.js 效果图如下: 引入结构: 实例化 ...

  7. python matplotlib笔记:饼状图

    1.饼状图参数: matplotlib.pyplot.pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance= ...

  8. python怎么画多重饼状图_Python通过matplotlib画双层饼图及环形图简单示例

    (1) 饼图(pie),即在一个圆圈内分成几块,显示不同数据系列的占比大小,这也是我们在日常数据的图形展示中最常用的图形之一. 在python中常用matplotlib的pie来绘制,基本命令如下所示 ...

  9. Matplotlib绘制好看的饼状图:电影类型数据的简单处理与可视化

    先放一张结果图. 数据预处理 首先,导入包. import pandas as pd import numpy as np import re import matplotlib.pyplot as ...

最新文章

  1. mysql开发java心得_关于mysql 一些优化心得
  2. 排序算法 | 快速排序,算法的图解、实现、复杂度和稳定性分析与优化
  3. python自动化办公:邮件篇 (定时邮件问候女票so easy)
  4. Java多线程(七)之同步器基础:AQS框架深入分析
  5. 安装配置Exchange 问题集
  6. linux contos7防火墙加端口,Linux:centos7防火墙开放端口
  7. js刷新页面有哪几种方法
  8. 前端学习与“IT界大佬告诉你,程序员接私活的7大平台利器”
  9. 不宜使用Selenium自动化的10个测试场景
  10. linux瘦身软件下载,瘦身相机APP全新安卓版下载-瘦身相机APPV1.3.0-Linux公社
  11. 冒泡排序java代码_面试官问我插入排序和冒泡排序哪个更牛逼?
  12. JSONP原理及使用
  13. mybatis支持拼音、汉字模糊查询
  14. json的格式是什么?
  15. Python 一维数据
  16. 基于WordPress搭建个人网站
  17. JavaScript-作用域和作用链
  18. 【智能优化算法】基于分段权重和变异反向学习的蝴蝶优化算法求解单目标优化问题附matlab代码
  19. 多益网络校招 —— web前端一面
  20. matplotlib实现多个子图的盒须图

热门文章

  1. 相机帧率与曝光的关系
  2. jetson nano 安装乐视的深度相机orbbec
  3. C语言实现json文本解析
  4. m3u8转换到mp4 python_Python 实现MP4视频转M3u8视频
  5. 从阿里云dms导出mysql无法导入_MySQL数据库怎么导入数据?怎么用DMS导入数据?...
  6. 08-20210305在WIN10下通过网口给华为海思Hi3516DV300刷机(鸿蒙系统)
  7. 命令行运行ktr和kjb
  8. 荧光染料BDP FL maleimide/马来酰亚胺,CAS:773859-49-7
  9. vue使用高德地图-进行显示地图和查询天气
  10. Python中复数取.imag的问题