Skip to content

Commit

Permalink
Coordinates enhance (pyecharts#463)
Browse files Browse the repository at this point in the history
* Refactor coordinates with Geo

* Refactor coordinates with Geoline

* Add test case for coordinate enhance

* Update test case

* Add datasets document

* Enhance features

1. Add rasise_exception parameter
2. Add test cases.

* Mini feature enhance

* Split Coordinate Search Function into two function

* Update test cases
  • Loading branch information
kinegratii authored and chfw committed Mar 25, 2018
1 parent ba7ee71 commit 6f62ca2
Show file tree
Hide file tree
Showing 13 changed files with 4,124 additions and 3,756 deletions.
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pyecharts 是一个用于生成 Echarts 图表的类库。Echarts 是百度开

**其他资源**

[示例项目](https://github.com/pyecharts/pyecharts-users-cases) | [地图扩展项目](https://github.com/pyecharts/echarts-china-cities-js)
[示例项目](https://github.com/pyecharts/pyecharts-users-cases) | [地理地图数据](zh-cn/datasets)

**项目开发**

Expand Down
2 changes: 1 addition & 1 deletion docs/en-us/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

**Other Resources**

[Demo Projects](https://github.com/pyecharts/pyecharts-users-cases) | [Map Extension](https://github.com/pyecharts/echarts-china-cities-js)
[Demo Projects](https://github.com/pyecharts/pyecharts-users-cases) | [Geography & Map](en-us/datasets)

**Development**

Expand Down
82 changes: 82 additions & 0 deletions docs/en-us/datasets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
> Datasets:This article describes the raw data and acces interface for builtin data.
## Overview

pyecharts contains a lot of data of geography and map, which is provided or can be installed and loaded.

## Geography Coordinates

### Raw Data

pyecharts contains some coordinates of cities, which are stored in the variable `pyecharts.datasets.coordinates._COORDINATE_DATASET` .

The format can be described as the following:

```
{<name>: [<longitude>, <latitude>]}
```

Example:

```python
_COORDINATE_DATASET = {
'阿城': [126.58, 45.32],
'阿克苏': [80.19, 41.09],
'阿勒泰': [88.12, 47.50],
...
}
```

### Get Coordinate

Function `get_coordinate(name)` returns coordinate for a city name.This funcion will return `None` if not found.

```python
from pyecharts.datasets.coordinates import get_coordinate

coordinate = get_coordinate('北京')
print(coordinate) # [116.46, 39.92]

coordinate1 = get_coordinate('A市')
print(coordinate1) # None
```

### Search Coordindates by Keyword

Function `search_coordinates_by_keyword(*args)` returns result list with one or multiple keywords.

Usage 1: Use single keyword

```python
from pyecharts.datasets.coordinates import search_coordinates_by_keyword

result = search_coordinates_by_keyword('北京')
print(result) # {'北京':[116.46, 39.92], '北京市': [116.4, 39.9]}
```

Usage 2: Use multiple keywords

```python
from pyecharts.datasets.coordinates import search_coordinates_by_keyword
result = search_coordinates_by_keyword('福州', '杭州')
print(result) # {'福州市': [119.3, 26.08], '杭州市': [120.15, 30.28] ...}
```

### Search Coordindates by Filter Function

Function `search_coordinates_by_filter(func)` returns result list with filter function.

Usage : Use filter function

```python
from pyecharts.datasets.coordinates import search_coordinates_by_filter

result = search_coordinates_by_filter(
func=lambda name: '福州' in name or '杭州' in name
)
print(result)
```

## Map Data

All map are hosted on https://github.com/echarts-maps
2 changes: 1 addition & 1 deletion docs/zh-cn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pyecharts 是一个用于生成 Echarts 图表的类库。Echarts 是百度开

**其他资源**

[示例项目](https://github.com/pyecharts/pyecharts-users-cases) | [地图扩展项目](https://github.com/pyecharts/echarts-china-cities-js)
[示例项目](https://github.com/pyecharts/pyecharts-users-cases) | [地理地图数据](zh-cn/datasets)

**项目开发**

Expand Down
79 changes: 79 additions & 0 deletions docs/zh-cn/datasets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
> 数据集 篇:本文档主要介绍 pyecharts 项目相关的原始数据和访问接口。
## 概述

pyecharts 项目包含了一系列的地理地图数据,这些数据或者已经内置,或者需要额外安装和加载。

## 地理经纬度坐标

### 原始数据

pyecharts 内置了一些常用的城市地理坐标数据,这些数据保存在 `pyecharts.datasets.coordinates._COORDINATE_DATASET` 这个字典常量中,格式可描述为以下形式:

```
{<name>: [<longitude>, <latitude>]}
```

示例

```python
_COORDINATE_DATASET = {
'阿城': [126.58, 45.32],
'阿克苏': [80.19, 41.09],
'阿勒泰': [88.12, 47.50],
...
}
```

### 检索地理坐标

`get_coordinate(name)` 返回城市名称的地理坐标,如果未定义将返回 None 。

```python
from pyecharts.datasets.coordinates import get_coordinate

coordinate = get_coordinate('北京')
print(coordinate) # [116.46, 39.92]

coordinate1 = get_coordinate('A市')
print(coordinate1) # None
```

### 按关键字搜索地理坐标

`search_coordinates_by_keyword(*args)` 根据一个或多个关键字,返回一个匹配的字典对象。

用法1:单个关键字模糊搜索

```python
from pyecharts.datasets.coordinates import search_coordinates_by_keyword

result = search_coordinates_by_keyword('北京')
print(result) # {'北京':[116.46, 39.92], '北京市': [116.4, 39.9]}
```

用法2:多个关键字模糊搜索

```python
from pyecharts.datasets.coordinates import search_coordinates_by_keyword
result = search_coordinates_by_keyword('福州', '杭州')
print(result) # {'福州市': [119.3, 26.08], '杭州市': [120.15, 30.28] ...}
```

### 按过滤函数搜索地理坐标

`search_coordinates_by_filter(func)` 根据过滤函数,返回一个匹配的字典对象。
用法(结果同上)

```python
from pyecharts.datasets.coordinates import search_coordinates_by_filter

result = search_coordinates_by_filter(
func=lambda name: '福州' in name or '杭州' in name
)
print(result)
```

## 地图数据

地图数据均托管在 https://github.com/echarts-maps
44 changes: 32 additions & 12 deletions pyecharts/charts/geo.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# coding=utf-8

import copy

from pyecharts.chart import Chart
from pyecharts.option import get_all_options
from pyecharts.constants import CITY_GEO_COORDS
from pyecharts.datasets.coordinates import get_coordinate


class Geo(Chart):
Expand All @@ -13,8 +11,34 @@ class Geo(Chart):
地理坐标系组件用于地图的绘制,支持在地理坐标系上绘制散点图,线集。
"""

def __init__(self, title="", subtitle="", **kwargs):
super(Geo, self).__init__(title, subtitle, **kwargs)
self._coordinates = {}

def add_coordinate(self, name, longitude, latitude):
"""
Add a geo coordinate for a position.
:param name: The name of a position
:param longitude: The longitude of coordinate.
:param latitude: The latitude of coordinate.
:return:
"""
self._coordinates.update({name: [longitude, latitude]})

def get_coordinate(self, name, raise_exception=False):
"""
Return coordinate for the city name.
:param name: City name or any custom name string.
:param raise_exception: Whether to raise exception if not exist.
:return: A list like [longitude, latitude] or None
"""
if name in self._coordinates:
return self._coordinates[name]
coordinate = get_coordinate(name)
if coordinate is None and raise_exception:
raise ValueError('No coordinate is specified for {}'.format(name))
return coordinate

def add(self, *args, **kwargs):
self.__add(*args, **kwargs)
Expand Down Expand Up @@ -69,18 +93,14 @@ def __add(self, name, attr, value,
chart = get_all_options(**kwargs)

if geo_cities_coords:
_geo_cities_coords = copy.deepcopy(geo_cities_coords)
else:
_geo_cities_coords = copy.deepcopy(CITY_GEO_COORDS)
for name, coord in geo_cities_coords.items():
self.add_coordinate(name, coord[0], coord[1])

_data = []
for _name, _value in zip(attr, value):
if _name in _geo_cities_coords:
city_coordinate = _geo_cities_coords.get(_name)
city_coordinate.append(_value)
_data.append({"name": _name, "value": city_coordinate})
else:
print("%s coordinates is not found" % _name)
_coordinate = self.get_coordinate(_name, raise_exception=True)
_data_value = [_coordinate[0], _coordinate[1], _value]
_data.append({"name": _name, "value": _data_value})
self._option.update(
geo={
"map": maptype,
Expand Down
48 changes: 38 additions & 10 deletions pyecharts/charts/geolines.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

from pyecharts.chart import Chart
from pyecharts.option import get_all_options
from pyecharts.constants import (CITY_GEO_COORDS, SYMBOL)
from pyecharts.datasets.coordinates import get_coordinate
from pyecharts.constants import SYMBOL


class GeoLines(Chart):
Expand All @@ -11,9 +12,35 @@ class GeoLines(Chart):
用于带有起点和终点信息的线数据的绘制,主要用于地图上的航线,路线的可视化。
"""

def __init__(self, title="", subtitle="", **kwargs):
super(GeoLines, self).__init__(title, subtitle, **kwargs)
self._zlevel = 1
self._coordinates = {}

def add_coordinate(self, name, longitude, latitude):
"""
Add a geo coordinate for a position.
:param name: The name of a position
:param longitude: The longitude of coordinate.
:param latitude: The latitude of coordinate.
:return:
"""
self._coordinates.update({name: [longitude, latitude]})

def get_coordinate(self, name, raise_exception=False):
"""
Return coordinate for the city name.
:param name: City name or any custom name string.
:param raise_exception: Whether to raise exception if not exist.
:return: A list like [longitude, latitude] or None
"""
if name in self._coordinates:
return self._coordinates[name]
coordinate = get_coordinate(name)
if coordinate is None and raise_exception:
raise ValueError('No coordinate is specified for {}'.format(name))
return coordinate

def add(self, *args, **kwargs):
self.__add(*args, **kwargs)
Expand Down Expand Up @@ -86,33 +113,34 @@ def __add(self, name, data,
chart = get_all_options(**kwargs)
self._zlevel += 1
if geo_cities_coords:
_geo_cities_coords = geo_cities_coords
else:
_geo_cities_coords = CITY_GEO_COORDS
for name, coord in geo_cities_coords.items():
self.add_coordinate(name, coord[0], coord[1])

if geo_effect_symbol == "plane":
geo_effect_symbol = SYMBOL['plane']

_data_lines, _data_scatter = [], []
for d in data:
_from_name, _to_name = d
_from_coordinate = self.get_coordinate(_from_name,
raise_exception=True)
_to_coordinate = self.get_coordinate(_to_name,
raise_exception=True)
_data_lines.append({
"fromName": _from_name,
"toName": _to_name,
"coords": [
_geo_cities_coords.get(_from_name, []),
_geo_cities_coords.get(_to_name, [])
_from_coordinate,
_to_coordinate
]
})
_from_v = _geo_cities_coords.get(_from_name, [])
_data_scatter.append({
"name": _from_name,
"value": _from_v + [0]
"value": [_from_coordinate[0], _from_coordinate[1], 0]
})
_to_v = _geo_cities_coords.get(_to_name, [])
_data_scatter.append({
"name": _to_name,
"value": _to_v + [0]
"value": [_to_coordinate[0], _to_coordinate[1], 0]
})

self._option.update(
Expand Down
Loading

0 comments on commit 6f62ca2

Please sign in to comment.