怎么将通过pyecharts生成的动态图形添加到html文件中啊?html文件中还有菜单栏可以跳转的那种,求解答!
不知道你这个问题是否已经解决, 如果还没有解决的话:这是本学期在大数据哲学与社会科学实验室做的第六次分享了。
第一次分享的是:
第二次分享的是:
第三次分享的是:
第四次分享的是:
第五次分享的是:
本次分享的是“如何利用pyecharts绘制炫酷的关系网络图?”
关系网络图简单来说就是由节点和边连接起来的图,绘制这种图需要用到pyecharts
库。
安装:
pip install pyecharts
官方地址:
https://github.com/pyecharts/pyecharts/
开源教程:
https://pyecharts.org/#/zh-cn/intro
关系网络图的节点:
class pyecharts.options.GraphNode
class GraphNode(
# 数据项名称。
name: Optional[str] = None,
# 该类目节点标记的大小,可以设置成诸如 10 这样单一的数字,也可以用数组分开表示宽和高,
# 例如 [20, 10] 表示标记宽为 20,高为 10。
symbol_size: Union[Numeric, Sequence, None] = None,
# 节点的初始 x 值。在不指定的时候需要指明layout属性选择布局方式。
x: Optional[Numeric] = None,
# 节点的初始 y 值。在不指定的时候需要指明layout属性选择布局方式。
y: Optional[Numeric] = None,
# 数据项所在类目的 index。
category: Optional[int] = None,
)
关系网络图的边:
class pyecharts.options.GraphLink
class GraphLink(
# 边的源节点名称的字符串,也支持使用数字表示源节点的索引。
source: Union[str, int, None] = None,
# 边的目标节点名称的字符串,也支持使用数字表示源节点的索引。
target: Union[str, int, None] = None,
# 边的数值,可以在力引导布局中用于映射到边的长度。
value: Optional[Numeric] = None,
)
节点分类的类目:
class pyecharts.options.GraphCategory
class GraphCategory(
# 类目名称,用于和 legend 对应以及格式化 tooltip 的内容。
name: Optional[str] = None,
)
关系网络图:
class pyecharts.charts.Graph
class Graph(
# 初始化配置项,参考 `global_options.InitOpts`
init_opts: opts.InitOpts = opts.InitOpts()
def add(
# 系列名称,用于 tooltip 的显示,legend 的图例筛选。
series_name: str,
# 关系图节点数据项列表,参考 `opts.GraphNode`
nodes: Sequence[Union[opts.GraphNode, dict]],
# 关系图节点间关系数据项列表,参考 `opts.GraphLink`
links: Sequence[Union[opts.GraphLink, dict]],
# 关系图节点分类的类目列表,参考 `opts.GraphCategory`
categories: Union[Sequence[Union[opts.GraphCategory, dict]], None] = None,
# 节点之间的斥力因子。
# 支持设置成数组表达斥力的范围,此时不同大小的值会线性映射到不同的斥力。值越大则斥力越大
repulsion: Numeric = 50,
# 图的布局。可选:
# 'none' 不采用任何布局,使用节点中提供的 x, y 作为节点的位置。
# 'circular' 采用环形布局。
# 'force' 采用力引导布局。
layout: str = "force",
# 是否开启鼠标缩放和平移漫游。
is_roam: bool = True,
# 是否在鼠标移到节点上的时候突出显示节点以及节点的边和邻接节点。
is_focusnode: bool = True,
# 是否旋转标签,默认不旋转。
is_rotate_label: bool = False,
# 标签配置项,参考 `series_options.LabelOpts`
label_opts: Union[opts.LabelOpts, dict] = opts.LabelOpts(),
# 关系边的公用线条样式。
linestyle_opts: Union[opts.LineStyleOpts, dict] = opts.LineStyleOpts(),
)
)
【例子】普通的关系网络图
from pyecharts import options as opts
from pyecharts.charts import Graph
nodes = [
{'name': '结点1', 'symbolSize': 10},
{'name': '结点2', 'symbolSize': 20},
{'name': '结点3', 'symbolSize': 30},
{'name': '结点4', 'symbolSize': 40},
{'name': '结点5', 'symbolSize': 50},
{'name': '结点6', 'symbolSize': 40},
{'name': '结点7', 'symbolSize': 30},
{'name': '结点8', 'symbolSize': 20}
]
links = []
for i in nodes:
for j in nodes:
links.append({'source': i.get('name'), 'target': j.get('name')})
G = Graph(init_opts=opts.InitOpts(width='900', height='500'))
G.add(
series_name='',
nodes=nodes,
links=links,
repulsion=8000
)
G.set_global_opts(title_opts=opts.TitleOpts(title='Graph-基本示例'))
G.render('graph_base.html')
【例子】带边信息的关系网络图
from pyecharts import options as opts
from pyecharts.charts import Graph
nodes = [
{'name': '结点1', 'symbolSize': 10},
{'name': '结点2', 'symbolSize': 20},
{'name': '结点3', 'symbolSize': 30},
{'name': '结点4', 'symbolSize': 40},
{'name': '结点5', 'symbolSize': 50},
{'name': '结点6', 'symbolSize': 60},
]
links = [
{'source': '结点1', 'target': '结点2', 'value': 2},
{'source': '结点2', 'target': '结点3', 'value': 3},
{'source': '结点3', 'target': '结点4', 'value': 4},
{'source': '结点4', 'target': '结点5', 'value': 5},
{'source': '结点5', 'target': '结点6', 'value': 6},
{'source': '结点6', 'target': '结点1', 'value': 7},
]
G = Graph(init_opts=opts.InitOpts(width='900', height='500'))
G.add(
series_name='',
nodes=nodes,
links=links,
repulsion=4000,
edge_label=opts.LabelOpts(is_show=True, position='middle', formatter='{b}的数据{c}')
)
G.set_global_opts(title_opts=opts.TitleOpts(title='Graph-带边信息的图'))
G.render('graph_with_edge_options.html')
【例子】NPM中的包依赖
NPM(Node Package Manager)的思路大概是这样的:
1.买个服务器作为代码仓库(registry),在里面放所有需要被共享的代码。
2.发邮件通知 jQuery、Bootstrap、Underscore 作者使用 npm publish 把代码提交到 registry 上,分别取名 jquery、bootstrap 和 underscore(注意大小写)。
3.社区里的其他人如果想使用这些代码,就把 jquery、bootstrap 和 underscore 写到 package.json 里,然后运行 npm install ,npm 就会帮他们下载代码。
4.下载完的代码出现在 node_modules 目录里,可以随意使用了。
这些可以被使用的代码被叫做「包」(package),这就是 NPM 名字的由来:Node Package(包) Manager(管理器)。
import json
from pyecharts import options as opts
from pyecharts.charts import Graph
with open(r'data/npmdepgraph.min10.json', 'r') as f:
data = json.load(f)
nodes = [
{
'x': node['x'],
'y': node['y'],
'name': node['label'],
'symbolSize': node['size'],
'itemStyle': {'color': node['color']}
}
for node in data['nodes']
]
edges = [
{
'source': edge['sourceID'],
'target': edge['targetID']
}
for edge in data['edges']
]
G = Graph(init_opts=opts.InitOpts(width='900', height='900'))
G.add(
series_name='',
nodes=nodes,
links=edges,
layout='none',
is_roam=True,
is_focusnode=True,
label_opts=opts.LabelOpts(is_show=True),
linestyle_opts=opts.LineStyleOpts(width=0.5, curve=0.3, opacity=0.7)
)
G.set_global_opts(title_opts=opts.TitleOpts(title='NPM Dependencies'))
G.render('npm_dependencies.html')
【例子】悲惨世界(les miserables)人物关系网络图
import json
from pyecharts import options as opts
from pyecharts.charts import Graph
with open(r'data/les-miserables.json', 'r') as f:
data = json.load(f)
nodes = []
idDict = dict()
for node in data['nodes']:
nodes.append(
{
'x': node['x'],
'y': node['y'],
'name': node['name'],
'symbolSize': node['symbolSize'],
'category': node['category'],
}
)
idDict[node['id']] = node['name']
links = [
{
'source': idDict[edge['source']],
'target': idDict[edge['target']],
}
for edge in data['links']
]
categories = [
{
'name': category['name']
}
for category in data['categories']
]
G = Graph(init_opts=opts.InitOpts(width='900', height='900'))
G.add(
series_name='',
nodes=nodes,
links=links,
categories=categories,
layout='circular',
is_rotate_label=True,
label_opts=opts.LabelOpts(position='right'),
linestyle_opts=opts.LineStyleOpts(color='source', curve=0.3, opacity=0.7)
)
G.set_global_opts(
title_opts=opts.TitleOpts(title='Les Miserables'),
legend_opts=opts.LegendOpts(orient='vertical', pos_left='2%', pos_top='20%')
)
G.render('graph_les_miserables.html')
layout='none'
时的图像:
layout='circular'
时的图像:
【例子】微博转发关系网络图
import json
from pyecharts import options as opts
from pyecharts.charts import Graph
with open(r'data/weibo.json', 'r',encoding='utf_8_sig') as f:
data = json.load(f)
nodes = [
{
'name': node['name'],
'symbolSize': node['symbolSize'],
'category': node['category'],
}
for node in data['nodes']
]
links = [
{
'source': edge['source'],
'target': edge['target'],
}
for edge in data['links']
]
categories = [
{
'name': category['name']
}
for category in data['categories']
]
G = Graph(init_opts=opts.InitOpts(width='900', height='900'))
G.add(
series_name='',
nodes=nodes,
links=links,
categories=categories,
repulsion=30,
label_opts=opts.LabelOpts(is_show=False),
linestyle_opts=opts.LineStyleOpts(curve=0.2)
)
G.set_global_opts(
title_opts=opts.TitleOpts(title='微博转发关系图'),
legend_opts=opts.LegendOpts(is_show=False)
)
G.render('graph_with_edge_options.html')
可以使用pyecharts中的Page()方法来实现菜单栏跳转页面和添加动态图形到html文件中。
具体步骤如下: 1. 首先需要安装phantomjs,可以按照参考资料中的步骤进行安装。 2. 在pyecharts中使用Page()方法创建一个可跳转的html文件,例如:
from pyecharts import Page, Bar, Line, Pie
# 创建一个Page对象
page = Page()
# 创建一个柱状图
data = [5, 20, 36, 10, 75, 90]
bar = Bar("我的第一个图表", "这里是副标题")
bar.add("bar", ["一", "二", "三", "四", "五", "六"], data)
# 创建一个折线图
line = Line("折线图示例")
attr = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
line.add("最高气温", attr, [11, 11, 15, 13, 12, 13, 10], mark_point=["max", "min"], mark_line=["average"])
line.add("最低气温", attr, [1, -2, 2, 5, 3, 2, 0], mark_point=["max", "min"], mark_line=["average"])
# 创建一个饼图
attr = ["{}天".format(i) for i in range(1, 6)]
v1 = [11, 12, 13, 10, 10]
pie = Pie("饼图示例", title_pos='center', width=900)
pie.add("", attr, v1, is_random=True, radius=[30, 75], rosetype='radius', is_legend_show=False, is_label_show=True)
# 把图表添加到Page对象里
page.add(bar)
page.add(line)
page.add(pie)
# 保存图表到本地html文件
page.render("mycharts.html")
from pyecharts import Page, Bar
from pyecharts_snapshot.main import make_a_snapshot
# 创建一个Page对象
page = Page()
# 创建一个柱状图
data = [5, 20, 36, 10, 75, 90]
bar = Bar("我的第一个图表", "这里是副标题")
bar.add("bar", ["一", "二", "三", "四", "五", "六"], data)
# 添加动态图形
bar.add(
"动态数据",
["一", "二", "三", "四", "五", "六"],
[None] * 6,
is_datazoom_show=True,
datazoom_type="both",
is_datazoom_extra_show=True,
)
# 保存动态图形为静态图形
make_a_snapshot(bar.render(), "mybar.png")
# 把图表添加到Page对象里
page.add(bar)
# 保存所有图表到本地html文件
page.render("mycharts.html")
注意事项: 1. 在添加动态图形时,需要使用make_a_snapshot()方法将动态图形保存为静态图形,并在Page()对象中添加静态图形。 2. make_a_snapshot()方法需要安装phantomjs,并将其添加到环境变量中。 3. 保存图表时,需要将动态图形和其他图表一起保存到同一html文件中,例如上面的代码中的mycharts.html文件。