Skip to content

Commit

Permalink
🔥 burn down npcast and pdcast. No longer they are reqired. Simply pas…
Browse files Browse the repository at this point in the history
…s on pandas index, values and numpy data type
  • Loading branch information
chfw committed Aug 6, 2017
1 parent d3d92c6 commit e8f7850
Show file tree
Hide file tree
Showing 14 changed files with 254 additions and 311 deletions.
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,15 @@ from pyecharts import Bar

index = pd.date_range('3/8/2017', periods=6, freq='M')
df1 = pd.DataFrame(np.random.randn(6), index=index)
dtvalue1, pdattr1 = Bar.pdcast(df1)

df2 = pd.DataFrame(np.random.randn(6), index=index)
dtvalue2, pdattr2 = Bar.pdcast(df2)

dtvalue1 = [i[0] for i in dtvalue1]
dtvalue2 = [i[0] for i in dtvalue2]

bar = Bar('Bar chart', 'Profit and loss situation')
bar.add('profit', pdattr1, dtvalue1)
bar.add('loss', pdattr2, dtvalue2)
bar.add('profit', df1.index, df1.values)
bar.add('loss', df2.index, df2.values)
bar.render()
```
![usage-1](https://github.com/chenjiandongx/pyecharts/blob/master/images/usage-1.png)
Expand Down
11 changes: 2 additions & 9 deletions document/doc_en_US.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,9 @@ cast(seq)
3. Dictionaries
{A1: B1, A2: B2, A3: B3, A4: B4} -- > k_lst[ A[i1, i2...] ], v_lst[ B[i1, i2...] ]

如果使用的是 Numpy 或者 Pandas,直接将数据放入 ```add()``` 方法也可能会出现问题,因为 ```add()``` 方法接受的是两个 list 列表。最后所有的配置项都是要经过 JSON 序列化的,像 int64 这种类型的数据在这个过程是会报错的。
it provides ```pdcast(pddata)``` and ``` npcast(npdata)``` methods to handle numpy & pandas data。
In the context of Numpy and/or Pandas, ```pdcast(pddata)``` and ``` npcast(npdata)``` methods, provided in 0.19.2 are no log required. Please see the advanced example in README.

pdcast(),It accepts Series or DataFrame types.
```python
@staticmethod
pdcast(pddata)
``` handle Series and DataFrame type in pandas, return value_lst and index_list ```
```
传入的类型为 Series、DataFrame 的话,pdcast() 会返回两个确保类型正确的列表(整个列表的数据类型为 float 或者 str,会先尝试转换为数值类型的 float,出现异常再尝试转换为 str 类型),value_lst 和 index_lst,分别为 Series.values/DataFrame.values 和 Series.index/DataFrame.index 列表。再将得到的数据传入 ```add()``` 方法即可(DataFrame 多个维度时返回一个嵌套列表。比较适合像 Radar, Parallel, HeatMap 这些需要传入嵌套列表([[ ], [ ]])数据的图表。)
If your DataFrame returns a transposed list(such as, [ [1], [2], [3] ]), you have to tranpose it by yourself (make it like [ 1, 2, 3 ] ). This transpose operation applies to Radar, Parallel, HeatMap.

Series type
```python
Expand Down
12 changes: 2 additions & 10 deletions document/doc_zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,8 @@ cast(seq)
3. 字典
{A1: B1, A2: B2, A3: B3, A4: B4} -- > k_lst[ A[i1, i2...] ], v_lst[ B[i1, i2...] ]

如果使用的是 Numpy 或者 Pandas,直接将数据放入 ```add()``` 方法也可能会出现问题,因为 ```add()``` 方法接受的是两个 list 列表。最后所有的配置项都是要经过 JSON 序列化的,像 int64 这种类型的数据在这个过程是会报错的。
在这里提供了 ```pdcast(pddata)`````` npcast(npdata)``` 两个方法,用于这两个库数据类型的处理。

pdcast(),接受的参数可以为 Series 或者 DataFrame 类型。
```python
@staticmethod
pdcast(pddata)
``` 用于处理 Pandas 中的 Series 和 DataFrame 类型,返回 value_lst, index_list 两个列表 ```
```
传入的类型为 Series、DataFrame 的话,pdcast() 会返回两个确保类型正确的列表(整个列表的数据类型为 float 或者 str,会先尝试转换为数值类型的 float,出现异常再尝试转换为 str 类型),value_lst 和 index_lst,分别为 Series.values/DataFrame.values 和 Series.index/DataFrame.index 列表。再将得到的数据传入 ```add()``` 方法即可(DataFrame 多个维度时返回一个嵌套列表。比较适合像 Radar, Parallel, HeatMap 这些需要传入嵌套列表([[ ], [ ]])数据的图表。)
如果使用的是 Numpy 或者 Pandas,0.19.2以前提供的 ```pdcast(pddata)`````` npcast(npdata)``` 两个方法在0.19.3之后不需再用了,用于这两个库数据类型的处理。
DataFrame 多个维度时返回一个嵌套列表。比较适合像 Radar, Parallel, HeatMap 这些需要传入嵌套列表([[ ], [ ]])数据的图表。

Series 类型
```python
Expand Down
54 changes: 18 additions & 36 deletions pyecharts/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,39 +358,6 @@ def cast(seq):
v_lst.append(v)
return k_lst, v_lst

@staticmethod
def npcast(npdata):
""" Convert the Numpy data into list type
:param npdata:
Numpy data -> ndarray
:return:
"""
try:
_npvalue = npdata.astype(float).tolist()
except:
_npvalue = npdata.astype(str).tolist()
return _npvalue

@staticmethod
def pdcast(pddata):
""" Convert the Pandas data into list type
Series.index -> attr(str/int)
Series.value -> value(str/int)
DataFrame -> [[], []], can be used on Radar chart or Parallel chart.
:param pddata:
Pandas data -> Series or DataFrame
:return:
"""
try:
_dtvalue = pddata.values.astype(float).tolist()
except:
_dtvalue = pddata.values.astype(str).tolist()
try:
_pdattr = pddata.index.astype(float).tolist()
except:
_pdattr = pddata.index.astype(str).tolist()
return _dtvalue, _pdattr

def _legend_visualmap_colorlst(self, is_visualmap=False, **kwargs):
""" config legend,visualmap and colorlst component.
Expand Down Expand Up @@ -422,7 +389,7 @@ def render_embed(self):
"""
embed = 'chart_component.html'
template = self._jinja2_env.get_template(embed)
my_option = json.dumps(self._option, indent=4, ensure_ascii=False)
my_option = json_dumps(self._option, indent=4)
html = template.render(myOption=my_option,
chart_id=uuid.uuid4().hex,
myWidth=self._width, myHeight=self._height)
Expand All @@ -443,7 +410,7 @@ def render(self, path="render.html"):
if s.get('type') == "liquidFill":
temple = "lq.html"
break
my_option = json.dumps(self._option, indent=4)
my_option = json_dumps(self._option, indent=4)
tmp = self._jinja2_env.get_template(temple)
html = tmp.render(myOption=my_option,
chart_id=uuid.uuid4().hex,
Expand All @@ -463,7 +430,7 @@ def _repr_html_(self):
:return:
"""
divid = datetime.datetime.now()
my_option = json.dumps(self._option, indent=4)
my_option = json_dumps(self._option, indent=4)
temple = 'notebook.html'
series = self._option.get("series")
map_keywords = {}
Expand Down Expand Up @@ -1153,3 +1120,18 @@ def _geo_cities(self):
'荆州': [112.239741, 30.335165],
'廊坊': [116.7, 39.53],
}


class PandasNumpyTypeEncoder(json.JSONEncoder):
def default(self, obj):
try:
return obj.astype(float).tolist()
except:
try:
return obj.astype(str).tolist()
except:
return json.JSONEncoder.default(self, obj)


def json_dumps(data, indent=0):
return json.dumps(data, indent=indent, cls=PandasNumpyTypeEncoder)
40 changes: 19 additions & 21 deletions pyecharts/charts/bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from pyecharts.base import Base
from pyecharts.option import get_all_options


class Bar(Base):
"""
<<< Bar chart >>>
Expand Down Expand Up @@ -33,24 +34,21 @@ def __add(self, name, x_axis, y_axis,
It specifies whether to stack category axis.
:param kwargs:
"""
if isinstance(x_axis, list) and isinstance(y_axis, list):
assert len(x_axis) == len(y_axis)
kwargs.update(x_axis=x_axis)
chart = get_all_options(**kwargs)
is_stack = "stack" if is_stack else ""
xaxis, yaxis = chart['xy_axis']
self._option.update(xAxis=xaxis, yAxis=yaxis)
self._option.get('legend')[0].get('data').append(name)
self._option.get('series').append({
"type": "bar",
"name": name,
"data": y_axis,
"stack": is_stack,
"label": chart['label'],
"markPoint": chart['mark_point'],
"markLine": chart['mark_line'],
"indexflag": self._option.get('_index_flag')
})
self._legend_visualmap_colorlst(**kwargs)
else:
raise TypeError("x_axis and y_axis must be list")
assert len(x_axis) == len(y_axis)
kwargs.update(x_axis=x_axis)
chart = get_all_options(**kwargs)
is_stack = "stack" if is_stack else ""
xaxis, yaxis = chart['xy_axis']
self._option.update(xAxis=xaxis, yAxis=yaxis)
self._option.get('legend')[0].get('data').append(name)
self._option.get('series').append({
"type": "bar",
"name": name,
"data": y_axis,
"stack": is_stack,
"label": chart['label'],
"markPoint": chart['mark_point'],
"markLine": chart['mark_line'],
"indexflag": self._option.get('_index_flag')
})
self._legend_visualmap_colorlst(**kwargs)
39 changes: 18 additions & 21 deletions pyecharts/charts/effectscatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,21 @@ def __add(self, name, x_value, y_value,
symbol size
:param kwargs:
"""
if isinstance(x_value, list) and isinstance(y_value, list):
assert len(x_value) == len(y_value)
kwargs.update(type="scatter")
chart = get_all_options(**kwargs)
xaxis, yaxis = chart['xy_axis']
self._option.update(xAxis=xaxis, yAxis=yaxis)
self._option.get('legend')[0].get('data').append(name)
self._option.get('series').append({
"type": "effectScatter",
"name": name,
"showEffectOn":"render",
"rippleEffect": chart['effect'],
"symbol": chart['symbol'],
"symbolSize": symbol_size,
"data": [list(z) for z in zip(x_value, y_value)],
"label": chart['label'],
"indexflag": self._option.get('_index_flag')
})
self._legend_visualmap_colorlst(**kwargs)
else:
raise TypeError("x_axis and y_axis must be list")
assert len(x_value) == len(y_value)
kwargs.update(type="scatter")
chart = get_all_options(**kwargs)
xaxis, yaxis = chart['xy_axis']
self._option.update(xAxis=xaxis, yAxis=yaxis)
self._option.get('legend')[0].get('data').append(name)
self._option.get('series').append({
"type": "effectScatter",
"name": name,
"showEffectOn":"render",
"rippleEffect": chart['effect'],
"symbol": chart['symbol'],
"symbolSize": symbol_size,
"data": [list(z) for z in zip(x_value, y_value)],
"label": chart['label'],
"indexflag": self._option.get('_index_flag')
})
self._legend_visualmap_colorlst(**kwargs)
38 changes: 18 additions & 20 deletions pyecharts/charts/funnel.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from pyecharts.base import Base
from pyecharts.option import get_all_options


class Funnel(Base):
"""
<<< Funnel chart >>>
Expand All @@ -26,23 +27,20 @@ def __add(self, name, attr, value, **kwargs):
value of attribute
:param kwargs:
"""
if isinstance(attr, list) and isinstance(value, list):
assert len(attr) == len(value)
chart = get_all_options(**kwargs)
_data = []
for data in zip(attr, value):
_name, _value = data
_data.append({"name": _name, "value": _value})
for a in attr:
self._option.get('legend')[0].get('data').append(a)
_dset = set(self._option.get('legend')[0].get('data'))
self._option.get('legend')[0].update(data=list(_dset))
self._option.get('series').append({
"type": "funnel",
"name": name,
"data": _data,
"label": chart['label']
})
self._legend_visualmap_colorlst(**kwargs)
else:
raise TypeError("attr and value must be list")
assert len(attr) == len(value)
chart = get_all_options(**kwargs)
_data = []
for data in zip(attr, value):
_name, _value = data
_data.append({"name": _name, "value": _value})
for a in attr:
self._option.get('legend')[0].get('data').append(a)
_dset = set(self._option.get('legend')[0].get('data'))
self._option.get('legend')[0].update(data=list(_dset))
self._option.get('series').append({
"type": "funnel",
"name": name,
"data": _data,
"label": chart['label']
})
self._legend_visualmap_colorlst(**kwargs)
104 changes: 51 additions & 53 deletions pyecharts/charts/geo.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,56 +47,54 @@ def __add(self, name, attr, value,
The color of the map area in emphasis state
:param kwargs:
"""
if isinstance(attr, list) and isinstance(value, list):
assert len(attr) == len(value)
chart = get_all_options(**kwargs)
_data = []
for data in zip(attr, value):
_name, _value = data
if _name in self._geo_cities:
_v = self._geo_cities.get(_name)
_v.append(_value)
_value = list(_v)
_data.append({"name": _name, "value": _value})
self._option.update(
geo={
"map": maptype,
"label": {},
"itemStyle": {"normal": {
"areaColor": geo_normal_color,
"borderColor": border_color},
"emphasis":{"areaColor": geo_emphasis_color}}
})
self._option.get('legend')[0].get('data').append(name)
if type == "scatter":
self._option.get('series').append({
"type": type,
"name": name,
"coordinateSystem": 'geo',
"symbol": chart['symbol'],
"symbolSize": symbol_size,
"data": _data,
"label": chart['label'],
})
elif type == "effectScatter":
self._option.get('series').append({
"type": type,
"name": name,
"coordinateSystem": 'geo',
"showEffectOn": "render",
"rippleEffect": chart['effect'],
"symbol": chart['symbol'],
"symbolSize": symbol_size,
"data": _data,
"label": chart['label'],
})
elif type == "heatmap":
self._option.get('series').append({
"type": type,
"name": name,
"coordinateSystem": 'geo',
"data": _data,
})
self._legend_visualmap_colorlst(**kwargs)
else:
raise TypeError("attr and value must be list")
assert len(attr) == len(value)
chart = get_all_options(**kwargs)
_data = []
for data in zip(attr, value):
_name, _value = data
if _name in self._geo_cities:
_v = self._geo_cities.get(_name)
_v.append(_value)
_value = list(_v)
_data.append({"name": _name, "value": _value})
self._option.update(
geo={
"map": maptype,
"label": {},
"itemStyle": {"normal": {
"areaColor": geo_normal_color,
"borderColor": border_color},
"emphasis":{"areaColor": geo_emphasis_color}}
})
self._option.get('legend')[0].get('data').append(name)
if type == "scatter":
self._option.get('series').append({
"type": type,
"name": name,
"coordinateSystem": 'geo',
"symbol": chart['symbol'],
"symbolSize": symbol_size,
"data": _data,
"label": chart['label'],
})
elif type == "effectScatter":
self._option.get('series').append({
"type": type,
"name": name,
"coordinateSystem": 'geo',
"showEffectOn": "render",
"rippleEffect": chart['effect'],
"symbol": chart['symbol'],
"symbolSize": symbol_size,
"data": _data,
"label": chart['label'],
})
elif type == "heatmap":
self._option.get('series').append({
"type": type,
"name": name,
"coordinateSystem": 'geo',
"data": _data,
})
self._legend_visualmap_colorlst(**kwargs)

Loading

0 comments on commit e8f7850

Please sign in to comment.