Skip to content

Commit

Permalink
add new charts type Sankeyy
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjiandongx committed Aug 24, 2017
1 parent c66c8a3 commit 6cf1bb7
Show file tree
Hide file tree
Showing 9 changed files with 320 additions and 10 deletions.
77 changes: 75 additions & 2 deletions docs/zh-cn/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pyecharts 是一个用于生成 Echarts 图表的类库。实际上就是 Echart
* [开始使用](https://github.com/chenjiandongx/pyecharts/blob/master/docs/zh-cn/documentation.md#开始使用)
* [通用配置项](https://github.com/chenjiandongx/pyecharts/blob/master/docs/zh-cn/documentation.md#通用配置项)
* xyAxis:直角坐标系中的 x、y 轴(Line、Bar、Scatter、EffectScatter、Kline)
* dataZoom:dataZoom 组件 用于区域缩放,从而能自由关注细节的数据信息,或者概览数据整体,或者去除离群点的影响。(Line、Bar、Scatter、EffectScatter、Kline)
* dataZoom:dataZoom 组件 用于区域缩放,从而能自由关注细节的数据信息,或者概览数据整体,或者去除离群点的影响。(Line、Bar、Scatter、EffectScatter、Kline、Boxplot)
* legend:图例组件。图例组件展现了不同系列的标记(symbol),颜色和名字。可以通过点击图例控制哪些系列不显示。
* label:图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。
* lineStyle:带线图形的线的风格选项(Line、Polar、Radar、Graph、Parallel)
Expand Down Expand Up @@ -36,6 +36,7 @@ pyecharts 是一个用于生成 Echarts 图表的类库。实际上就是 Echart
* Pie(饼图)
* Polar(极坐标系)
* Radar(雷达图)
* Sankey(桑基图)
* Scatter(散点图)
* Scatter3D(3D 散点图)
* WordCloud(词云图)
Expand Down Expand Up @@ -369,6 +370,8 @@ cast(seq)
线的弯曲程度,0 为完全不弯曲,1 为最弯曲。默认为 0
* line_type -> str
线的类型,有'solid', 'dashed', 'dotted'可选。默认为'solid'
* line_color -> str
线的颜色


**grid3D:3D 笛卡尔坐标系组配置项,适用于 3D 图形。(Bar3D, Line3D, Scatter3D)**
Expand Down Expand Up @@ -1832,6 +1835,76 @@ radar.render()
![radar-2](https://github.com/chenjiandongx/pyecharts/blob/master/images/radar-2.gif)


## Sankey(桑基图)
> 是一种特殊的流图, 它主要用来表示原材料、能量等如何从初始形式经过中间过程的加工、转化到达最终形式。
Sankey.add() 方法签名
```python
add(name, nodes, links, sankey_node_width=20, sankey_node_gap=8, **kwargs)
```
* name -> str
图例名称
* nodes -> list
桑基图结点,必须包含的数据项有:
* name:数据项名称
* value:数据项数值
* links -> list
桑基图结点关系
* source:边的源节点名称(必须有!)
* target:边的目标节点名称(必须有!)
* vaule:边的数值,决定边的宽度。
* sankey_node_width -> int
图中每个矩形节点的宽度。默认为 20
* sankey_node_gap -> int
图中每一列任意两个矩形节点之间的间隔。默认为 8

先来个简单示例
```python
from pyecharts import Sankey

nodes = [
{'name': 'category1'}, {'name': 'category2'}, {'name': 'category3'},
{'name': 'category4'}, {'name': 'category5'}, {'name': 'category6'},
]

links = [
{'source': 'category1', 'target': 'category2', 'value': 10},
{'source': 'category2', 'target': 'category3', 'value': 15},
{'source': 'category3', 'target': 'category4', 'value': 20},
{'source': 'category5', 'target': 'category6', 'value': 25}
]
sankey = Sankey("桑基图示例", width=1200, height=600)
sankey.add("sankey", nodes, links, line_opacity=0.2,
line_curve=0.5, line_color='source', is_label_show=True, label_pos='right')
sankey.render()
```
![sankey-0](https://github.com/chenjiandongx/pyecharts/blob/master/images/sankey-0.png)

使用官方提供的 json 数据
```python
import sys
import os
import json

from pyecharts import Sankey

PY2 = sys.version_info[0] == 2

if PY2:
import codecs
with codecs.open(os.path.join("..", "json", "energy.json"), "rb") as f:
j = json.load(f)
else:
with open(os.path.join("..", "json", "energy.json"), "r", encoding="utf-8") as f:
j = json.load(f)
sankey = Sankey("桑基图示例", width=1200, height=600)
sankey.add("sankey", nodes=j['nodes'], links=j['links'], line_opacity=0.2,
line_curve=0.5, line_color='source', is_label_show=True, label_pos='right')
sankey.render()
```
![sankey-1](https://github.com/chenjiandongx/pyecharts/blob/master/images/sankey-1.png)


## Scatter(散点图)
> 直角坐标系上的散点图可以用来展现数据的 x,y 之间的关系,如果数据项有多个维度,可以用颜色来表现,利用 geo 组件。
Expand Down Expand Up @@ -1994,7 +2067,7 @@ wordcloud.render()
# 用户自定义

## Grid:并行显示多张图
> 用户可以自定义结合 Line/Bar/Kline/Scatter/EffectScatter/Pie/HeatMap 图表,将不同类型图表画在多张图上。第一个图需为 有 x/y 轴的图,即不能为 Pie,其他位置顺序任意。
> 用户可以自定义结合 Line/Bar/Kline/Scatter/EffectScatter/Pie/HeatMap/Boxplot 图表,将不同类型图表画在多张图上。第一个图需为 有 x/y 轴的图,即不能为 Pie,其他位置顺序任意。
Grid 类的使用:
1. 引入 `Grid` 类,`from pyecharts import Grid`
Expand Down
Binary file added images/sankey-0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/sankey-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
120 changes: 120 additions & 0 deletions json/energy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
{"nodes":[
{"name":"Agricultural 'waste'"},
{"name":"Bio-conversion"},
{"name":"Liquid"},
{"name":"Losses"},
{"name":"Solid"},
{"name":"Gas"},
{"name":"Biofuel imports"},
{"name":"Biomass imports"},
{"name":"Coal imports"},
{"name":"Coal"},
{"name":"Coal reserves"},
{"name":"District heating"},
{"name":"Industry"},
{"name":"Heating and cooling - commercial"},
{"name":"Heating and cooling - homes"},
{"name":"Electricity grid"},
{"name":"Over generation / exports"},
{"name":"H2 conversion"},
{"name":"Road transport"},
{"name":"Agriculture"},
{"name":"Rail transport"},
{"name":"Lighting & appliances - commercial"},
{"name":"Lighting & appliances - homes"},
{"name":"Gas imports"},
{"name":"Ngas"},
{"name":"Gas reserves"},
{"name":"Thermal generation"},
{"name":"Geothermal"},
{"name":"H2"},
{"name":"Hydro"},
{"name":"International shipping"},
{"name":"Domestic aviation"},
{"name":"International aviation"},
{"name":"National navigation"},
{"name":"Marine algae"},
{"name":"Nuclear"},
{"name":"Oil imports"},
{"name":"Oil"},
{"name":"Oil reserves"},
{"name":"Other waste"},
{"name":"Pumped heat"},
{"name":"Solar PV"},
{"name":"Solar Thermal"},
{"name":"Solar"},
{"name":"Tidal"},
{"name":"UK land based bioenergy"},
{"name":"Wave"},
{"name":"Wind"}
],
"links":[
{"source": "Agricultural 'waste'", "target": "Bio-conversion", "value": 124.729},
{"source": "Bio-conversion", "target": "Liquid", "value": 0.597},
{"source": "Bio-conversion", "target": "Losses", "value": 26.862},
{"source": "Bio-conversion", "target": "Solid", "value": 280.322},
{"source": "Bio-conversion", "target": "Gas", "value": 81.144},
{"source": "Biofuel imports", "target": "Liquid", "value": 35},
{"source": "Biomass imports", "target": "Solid", "value": 35},
{"source": "Coal imports", "target": "Coal", "value": 11.606},
{"source": "Coal reserves","target": "Coal", "value": 63.965},
{"source": "Coal", "target": "Solid", "value": 75.571},
{"source": "District heating", "target": "Industry", "value": 10.639},
{"source": "District heating", "target": "Heating and cooling - commercial", "value": 22.505},
{"source": "District heating", "target": "Heating and cooling - homes", "value": 46.184},
{"source": "Electricity grid", "target": "Over generation / exports", "value": 104.453},
{"source": "Electricity grid", "target": "Heating and cooling - homes", "value": 113.726},
{"source": "Electricity grid", "target": "H2 conversion", "value": 27.14},
{"source": "Electricity grid", "target": "Industry", "value": 342.165},
{"source": "Electricity grid", "target": "Road transport", "value": 37.797},
{"source": "Electricity grid", "target": "Agriculture", "value": 4.412},
{"source": "Electricity grid", "target": "Heating and cooling - commercial", "value": 40.858},
{"source": "Electricity grid", "target": "Losses", "value": 56.691},
{"source": "Electricity grid", "target": "Rail transport", "value": 7.863},
{"source": "Electricity grid", "target": "Lighting & appliances - commercial", "value": 90.008},
{"source": "Electricity grid", "target": "Lighting & appliances - homes", "value": 93.494},
{"source": "Gas imports", "target": "Ngas", "value": 40.719},
{"source": "Gas reserves", "target": "Ngas", "value": 82.233},
{"source": "Gas", "target": "Heating and cooling - commercial", "value": 0.129},
{"source": "Gas", "target": "Losses", "value": 1.401},
{"source": "Gas", "target": "Thermal generation", "value": 151.891},
{"source": "Gas", "target": "Agriculture", "value": 2.096},
{"source": "Gas", "target": "Industry", "value": 48.58},
{"source": "Geothermal", "target": "Electricity grid", "value": 7.013},
{"source": "H2 conversion", "target": "H2", "value": 20.897},
{"source": "H2 conversion", "target": "Losses", "value": 6.242},
{"source": "H2", "target": "Road transport", "value": 20.897},
{"source": "Hydro", "target": "Electricity grid", "value": 6.995},
{"source": "Liquid", "target": "Industry", "value": 121.066},
{"source": "Liquid", "target": "International shipping", "value": 128.69},
{"source": "Liquid", "target": "Road transport", "value": 135.835},
{"source": "Liquid", "target": "Domestic aviation", "value": 14.458},
{"source": "Liquid", "target": "International aviation", "value": 206.267},
{"source": "Liquid", "target": "Agriculture", "value": 3.64},
{"source": "Liquid", "target": "National navigation", "value": 33.218},
{"source": "Liquid", "target": "Rail transport", "value": 4.413},
{"source": "Marine algae", "target": "Bio-conversion", "value": 4.375},
{"source": "Ngas", "target": "Gas", "value": 122.952},
{"source": "Nuclear", "target": "Thermal generation", "value": 839.978},
{"source": "Oil imports", "target": "Oil", "value": 504.287},
{"source": "Oil reserves", "target": "Oil", "value": 107.703},
{"source": "Oil", "target": "Liquid", "value": 611.99},
{"source": "Other waste", "target": "Solid", "value": 56.587},
{"source": "Other waste", "target": "Bio-conversion", "value": 77.81},
{"source": "Pumped heat", "target": "Heating and cooling - homes", "value": 193.026},
{"source": "Pumped heat", "target": "Heating and cooling - commercial", "value": 70.672},
{"source": "Solar PV", "target": "Electricity grid", "value": 59.901},
{"source": "Solar Thermal", "target": "Heating and cooling - homes", "value": 19.263},
{"source": "Solar", "target": "Solar Thermal", "value": 19.263},
{"source": "Solar", "target": "Solar PV", "value": 59.901},
{"source": "Solid", "target": "Agriculture", "value": 0.882},
{"source": "Solid", "target": "Thermal generation", "value": 400.12},
{"source": "Solid", "target": "Industry", "value": 46.477},
{"source": "Thermal generation", "target": "Electricity grid", "value": 525.531},
{"source": "Thermal generation", "target": "Losses", "value": 787.129},
{"source": "Thermal generation", "target": "District heating", "value": 79.329},
{"source": "Tidal", "target": "Electricity grid", "value": 9.452},
{"source": "UK land based bioenergy", "target": "Bio-conversion", "value": 182.01},
{"source": "Wave", "target": "Electricity grid", "value": 19.013},
{"source": "Wind", "target": "Electricity grid", "value": 289.366}
]}
1 change: 1 addition & 0 deletions pyecharts/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from pyecharts.charts.pie import Pie
from pyecharts.charts.polar import Polar
from pyecharts.charts.radar import Radar
from pyecharts.charts.sankey import Sankey
from pyecharts.charts.scatter import Scatter
from pyecharts.charts.scatter3D import Scatter3D
from pyecharts.charts.wordcloud import WordCloud
Expand Down
1 change: 1 addition & 0 deletions pyecharts/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ def add(self, angle_data=None,
line_opacity=None,
line_type=None,
line_width=None,
line_color=None,
liquid_color=None,
maptype=None,
mark_line=None,
Expand Down
63 changes: 63 additions & 0 deletions pyecharts/charts/sankey.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env python
# coding=utf-8

from pyecharts.base import Base
from pyecharts.option import get_all_options


class Sankey(Base):
"""
<<< Sankey chart >>>
Sankey graphs are a specific type of streamgraphs, in which the width of each branch is
shown proportionally to the flow quantity. These graphs are typically used to
visualize energy or material or cost transfers between processes.
They can also visualize the energy accounts, material flow accounts on a regional or
national level, and also the breakdown of cost of item or services.
"""

def __init__(self, title="", subtitle="", **kwargs):
super(Sankey, self).__init__(title, subtitle, **kwargs)

def add(self, *args, **kwargs):
self.__add(*args, **kwargs)

def __add(self, name, nodes, links,
sankey_node_width=20,
sankey_node_gap=8,
**kwargs):
"""
:param name:
Series name used for displaying in tooltip and filtering with legend,
or updating data and configuration with setOption.
:param nodes:
Relational nodes data
name:Name of data item. # required!!
value: Value of data item. # required!!
:param links:
Relational data between nodes
source:name of source node on edge # required!!
target:name of target node on edge # required!!
value:value of edge,It can be used in the force layout to map to the length of the edge
:param sankey_node_width:
The node width of rectangle in graph.
:param sankey_node_gap:
The gap between any two regtangles in each column from the graph.
:param kwargs:
:return:
"""
chart = get_all_options(**kwargs)
self._option.get('legend')[0].get('data').append(name)
self._option.get('series').append({
"type": "sankey",
"name": name,
"layout": None,
"data": nodes,
"links": links,
"nodeWidth": sankey_node_width,
"nodeGap": sankey_node_gap,
"label": chart['label'],
"lineStyle": chart['line_style'],
})
self._legend_visualmap_colorlst(**kwargs)
25 changes: 17 additions & 8 deletions pyecharts/option.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,13 @@ def label(type=None,
if label_pos is None:
label_pos = "outside" if type in ["pie", "graph"] else "top"
_label = {
"normal": {"show": is_label_show,
"position": label_pos,
"textStyle": {"color": label_text_color,
"fontSize": label_text_size}},
"normal": {
"show": is_label_show,
"position": label_pos,
"textStyle": {
"color": label_text_color,
"fontSize": label_text_size
}},
"emphasis": {"show": is_emphasis}
}

Expand Down Expand Up @@ -108,6 +111,7 @@ def line_style(line_width=1,
line_opacity=1,
line_curve=0,
line_type="solid",
line_color=None,
**kwargs):
"""
Expand All @@ -121,14 +125,19 @@ def line_style(line_width=1,
The larger the value, the greater the curvature. -> Graph
:param line_type:
Line type,it can be 'solid', 'dashed', 'dotted'
:param line_color:
color of line
:param kwargs:
:return:
"""
_line_style = {
"normal": {"width": line_width,
"opacity": line_opacity,
"curveness": line_curve,
"type": line_type}
"normal": {
"width": line_width,
"opacity": line_opacity,
"curveness": line_curve,
"type": line_type,
"color": line_color
}
}
return _line_style

Expand Down
Loading

0 comments on commit 6cf1bb7

Please sign in to comment.