"""
author:魏振东
date:20200303
func:微信好友性别可视化-饼状图
"""
from pyecharts.charts import Pie
from pyecharts import options as opts
import csv
def getSex(filename):
lstsex = []
with open(filename,'r') as f:
reader =csv.reader(f)
for i in reader:
lstsex.append(i[24])
return lstsex
def VisualSexpyechart(lstsex):
sex = dict()
for f in lstsex[1:]:
if f =='1':
sex['man'] = sex.get('man',0)+1
elif f == '2':
sex['women'] = sex.get('women',0)+1
else:
sex['unknown'] = sex.get('unknown',0)+1
total = len(lstsex[1:])
if sex['man']>sex['women']:
print("你很受大哥哥们的欢迎!男生人数比女生人数多{0}".format(sex['man']-sex['women']))
elif sex['man']<sex['women']:
print("你很受小姐姐们的欢迎!男生人数比女生人数多{0}".format(sex['women'] - sex['man']))
else:
print("男女通杀!")
attr = ['男性好友','女性好友','未知性别']
value = [sex['man'],sex['women'],sex['unknown']]
"""
class InitOpts(
# 图表画布宽度,css 长度单位。
width: str = "900px",
# 图表画布高度,css 长度单位。
height: str = "500px",
# 图表 ID,图表唯一标识,用于在多图表时区分。
chart_id: Optional[str] = None,
# 渲染风格,可选 "canvas", "svg"
# # 参考 `全局变量` 章节
renderer: str = RenderType.CANVAS,
# 网页标题
page_title: str = "Awesome-pyecharts",
# 图表主题
theme: str = "white",
# 图表背景颜色
bg_color: Optional[str] = None,
# 远程 js host,如不设置默认为 https://assets.pyecharts.org/assets/"
# 参考 `全局变量` 章节
js_host: str = "",
# 画图动画初始化配置,参考 `global_options.AnimationOpts`
animation_opts: Union[AnimationOpts, dict] = AnimationOpts(),
)
"""
init_opts = opts.InitOpts(page_title="微信好友性别比例")
pie = Pie(init_opts=init_opts)
"""
class TitleOpts(
# 主标题文本,支持使用 \n 换行。
title: Optional[str] = None,
# 主标题跳转 URL 链接
title_link: Optional[str] = None,
# 主标题跳转链接方式
# 默认值是: blank
# 可选参数: 'self', 'blank'
# 'self' 当前窗口打开; 'blank' 新窗口打开
title_target: Optional[str] = None,
# 副标题文本,支持使用 \n 换行。
subtitle: Optional[str] = None,
# 副标题跳转 URL 链接
subtitle_link: Optional[str] = None,
# 副标题跳转链接方式
# 默认值是: blank
# 可选参数: 'self', 'blank'
# 'self' 当前窗口打开; 'blank' 新窗口打开
subtitle_target: Optional[str] = None,
# title 组件离容器左侧的距离。
# left 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比,
# 也可以是 'left', 'center', 'right'。
# 如果 left 的值为'left', 'center', 'right',组件会根据相应的位置自动对齐。
pos_left: Optional[str] = None,
# title 组件离容器右侧的距离。
# right 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比。
pos_right: Optional[str] = None,
# title 组件离容器上侧的距离。
# top 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比,
# 也可以是 'top', 'middle', 'bottom'。
# 如果 top 的值为'top', 'middle', 'bottom',组件会根据相应的位置自动对齐。
pos_top: Optional[str] = None,
# title 组件离容器下侧的距离。
# bottom 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比。
pos_bottom: Optional[str] = None,
# 标题内边距,单位px,默认各方向内边距为5,接受数组分别设定上右下左边距。
# // 设置内边距为 5
# padding: 5
# // 设置上下的内边距为 5,左右的内边距为 10
# padding: [5, 10]
# // 分别设置四个方向的内边距
# padding: [
# 5, // 上
# 10, // 右
# 5, // 下
# 10, // 左
# ]
padding: Union[Sequence, Numeric] = 5,
# 主副标题之间的间距。
item_gap: Numeric = 10,
# 主标题字体样式配置项,参考 `series_options.TextStyleOpts`
title_textstyle_opts: Union[TextStyleOpts, dict, None] = None,
# 副标题字体样式配置项,参考 `series_options.TextStyleOpts`
subtitle_textstyle_opts: Union[TextStyleOpts, dict, None] = None,
)
"""
title = opts.TitleOpts(title="微信好友性别比例",
subtitle="好友总人数{0}".format(total),
pos_left='center')
"""
class LegendOpts(
# 图例的类型。可选值:
# 'plain':普通图例。缺省就是普通图例。
# 'scroll':可滚动翻页的图例。当图例数量较多时可以使用。
type_: Optional[str] = None,
# 图例选择的模式,控制是否可以通过点击图例改变系列的显示状态。默认开启图例选择,可以设成 false 关闭
# 除此之外也可以设成 'single' 或者 'multiple' 使用单选或者多选模式。
selected_mode: Union[str, bool, None] = None,
# 是否显示图例组件
is_show: bool = True,
# 图例组件离容器左侧的距离。
# left 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比,
# 也可以是 'left', 'center', 'right'。
# 如果 left 的值为'left', 'center', 'right',组件会根据相应的位置自动对齐。
pos_left: Union[str, Numeric, None] = None,
# 图例组件离容器右侧的距离。
# right 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比。
pos_right: Union[str, Numeric, None] = None,
# 图例组件离容器上侧的距离。
# top 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比,
# 也可以是 'top', 'middle', 'bottom'。
# 如果 top 的值为'top', 'middle', 'bottom',组件会根据相应的位置自动对齐。
pos_top: Union[str, Numeric, None] = None,
# 图例组件离容器下侧的距离。
# bottom 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比。
pos_bottom: Union[str, Numeric, None] = None,
# 图例列表的布局朝向。可选:'horizontal', 'vertical'
orient: Optional[str] = None,
# 图例标记和文本的对齐。默认自动(auto)
# 根据组件的位置和 orient 决定
# 当组件的 left 值为 'right' 以及纵向布局(orient 为 'vertical')的时候为右对齐,即为 'right'。
# 可选参数: `auto`, `left`, `right`
align: Optional[str] = None,
# 图例内边距,单位px,默认各方向内边距为5
padding: int = 5,
# 图例每项之间的间隔。横向布局时为水平间隔,纵向布局时为纵向间隔。
# 默认间隔为 10
item_gap: int = 10,
# 图例标记的图形宽度。默认宽度为 25
item_width: int = 25,
# 图例标记的图形高度。默认高度为 14
item_height: int = 14,
# 图例关闭时的颜色。默认是 #ccc
inactive_color: Optional[str] = None,
# 图例组件字体样式,参考 `series_options.TextStyleOpts`
textstyle_opts: Union[TextStyleOpts, dict, None] = None,
# 图例项的 icon。
# ECharts 提供的标记类型包括 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none'
# 可以通过 'image://url' 设置为图片,其中 URL 为图片的链接,或者 dataURI。
# 可以通过 'path://' 将图标设置为任意的矢量路径。
legend_icon: Optional[str] = None,
)
"""
legend_opts = opts.LegendOpts(orient="vertical",
pos_top="20%",
pos_left="15%")
"""
class ToolBoxFeatureOpts(
# 保存为图片
save_as_image: Optional[dict] = None,
# 配置项还原
restore: Optional[dict] = None,
# 数据视图工具,可以展现当前图表所用的数据,编辑后可以动态更新
data_view: Optional[dict] = None,
# 数据区域缩放。目前只支持直角坐标系的缩放
data_zoom: Optional[dict] = None,
)
"""
"""
class ToolboxOpts(
# 是否显示工具栏组件
is_show: bool = True,
# 工具栏 icon 的布局朝向。
# 可选:'horizontal', 'vertical'
orient: str = "horizontal",
# 工具栏组件离容器左侧的距离。
# left 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比,
# 也可以是 'left', 'center', 'right'。
# 如果 left 的值为'left', 'center', 'right',组件会根据相应的位置自动对齐
pos_left: str = "80%",
# 工具栏组件离容器右侧的距离。
# right 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比。
pos_right: Optional[str] = None,
# 工具栏组件离容器上侧的距离。
# top 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比,
# 也可以是 'top', 'middle', 'bottom'。
# 如果 top 的值为'top', 'middle', 'bottom',组件会根据相应的位置自动对齐。
pos_top: Optional[str] = None,
# 工具栏组件离容器下侧的距离。
# bottom 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比。
pos_bottom: Optional[str] = None,
# 各工具配置项,参考 `global_options.ToolBoxFeatureOpts`
feature: Union[ToolBoxFeatureOpts, dict] = ToolBoxFeatureOpts(),
)
"""
toolbox_opts = opts.ToolboxOpts(orient="vertical",
pos_top="35%",
pos_right="15%"
)
pie.set_global_opts(title_opts=title,
legend_opts=legend_opts,
toolbox_opts = toolbox_opts
)
"""
class LabelOpts(
# 是否显示标签。
is_show: bool = True,
# 标签的位置。可选
# 'top','left','right','bottom','inside','insideLeft','insideRight'
# 'insideTop','insideBottom', 'insideTopLeft','insideBottomLeft'
# 'insideTopRight','insideBottomRight'
position: Union[str, Sequence] = "top",
# 文字的颜色。
# 如果设置为 'auto',则为视觉映射得到的颜色,如系列色。
color: Optional[str] = None,
# 文字的字体大小
font_size: Numeric = 12,
# 文字字体的风格,可选:
# 'normal','italic','oblique'
font_style: Optional[str] = None,
# 文字字体的粗细,可选:
# 'normal','bold','bolder','lighter'
font_weight: Optional[str] = None,
# 文字的字体系列
# 还可以是 'serif' , 'monospace', 'Arial', 'Courier New', 'Microsoft YaHei', ...
font_family: Optional[str] = None,
# 标签旋转。从 -90 度到 90 度。正值是逆时针。
rotate: Optional[Numeric] = None,
# 刻度标签与轴线之间的距离。
margin: Optional[Numeric] = 8,
# 坐标轴刻度标签的显示间隔,在类目轴中有效。
# 默认会采用标签不重叠的策略间隔显示标签。
# 可以设置成 0 强制显示所有标签。
# 如果设置为 1,表示『隔一个标签显示一个标签』,如果值为 2,表示隔两个标签显示一个标签,以此类推。
# 可以用数值表示间隔的数据,也可以通过回调函数控制。回调函数格式如下:
# (index:number, value: string) => boolean
# 第一个参数是类目的 index,第二个值是类目名称,如果跳过则返回 false。
interval: Union[Numeric, str, None]= None,
# 文字水平对齐方式,默认自动。可选:
# 'left','center','right'
horizontal_align: Optional[str] = None,
# 文字垂直对齐方式,默认自动。可选:
# 'top','middle','bottom'
vertical_align: Optional[str] = None,
# 标签内容格式器,支持字符串模板和回调函数两种形式,字符串模板与回调函数返回的字符串均支持用 \n 换行。
# 模板变量有 {a}, {b},{c},{d},{e},分别表示系列名,数据名,数据值等。
# 在 trigger 为 'axis' 的时候,会有多个系列的数据,此时可以通过 {a0}, {a1}, {a2} 这种后面加索引的方式表示系列的索引。
# 不同图表类型下的 {a},{b},{c},{d} 含义不一样。 其中变量{a}, {b}, {c}, {d}在不同图表类型下代表数据含义为:
# 折线(区域)图、柱状(条形)图、K线图 : {a}(系列名称),{b}(类目值),{c}(数值), {d}(无)
# 散点图(气泡)图 : {a}(系列名称),{b}(数据名称),{c}(数值数组), {d}(无)
# 地图 : {a}(系列名称),{b}(区域名称),{c}(合并数值), {d}(无)
# 饼图、仪表盘、漏斗图: {a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)
# 示例:formatter: '{b}: {@score}'
#
# 回调函数,回调函数格式:
# (params: Object|Array) => string
# 参数 params 是 formatter 需要的单个数据集。格式如下:
# {
# componentType: 'series',
# // 系列类型
# seriesType: string,
# // 系列在传入的 option.series 中的 index
# seriesIndex: number,
# // 系列名称
# seriesName: string,
# // 数据名,类目名
# name: string,
# // 数据在传入的 data 数组中的 index
# dataIndex: number,
# // 传入的原始数据项
# data: Object,
# // 传入的数据值
# value: number|Array,
# // 数据图形的颜色
# color: string,
# }
formatter: Optional[str] = None,
# 在 rich 里面,可以自定义富文本样式。利用富文本样式,可以在标签中做出非常丰富的效果
# 具体配置可以参考一下 https://www.echartsjs.com/tutorial.html#%E5%AF%8C%E6%96%87%E6%9C%AC%E6%A0%87%E7%AD%BE
rich: Optional[dict] = None,
)
"""
"""
def add(
# 系列名称,用于 tooltip 的显示,legend 的图例筛选。
series_name: str,
# 系列数据项,格式为 [(key1, value1), (key2, value2)]
data_pair: Sequence,
# 系列 label 颜色
color: Optional[str] = None,
# 饼图的半径,数组的第一项是内半径,第二项是外半径
# 默认设置成百分比,相对于容器高宽中较小的一项的一半
radius: Optional[Sequence] = None,
# 饼图的中心(圆心)坐标,数组的第一项是横坐标,第二项是纵坐标
# 默认设置成百分比,设置成百分比时第一项是相对于容器宽度,第二项是相对于容器高度
center: Optional[Sequence] = None,
# 是否展示成南丁格尔图,通过半径区分数据大小,有'radius'和'area'两种模式。
# radius:扇区圆心角展现数据的百分比,半径展现数据的大小
# area:所有扇区圆心角相同,仅通过半径展现数据大小
rosetype: Optional[str] = None,
# 饼图的扇区是否是顺时针排布。
is_clockwise: bool = True,
# 标签配置项,参考 `series_options.LabelOpts`
label_opts: Union[opts.LabelOpts, dict] = opts.LabelOpts(),
# 提示框组件配置项,参考 `series_options.TooltipOpts`
tooltip_opts: Union[opts.TooltipOpts, dict, None] = None,
# 图元样式配置项,参考 `series_options.ItemStyleOpts`
itemstyle_opts: Union[opts.ItemStyleOpts, dict, None] = None,
)
"""
pie.add("",
[list(z) for z in zip(attr,value)],
radius=[30, 75],
center=['50%','50%'],
rosetype ="area",
label_opts=opts.LabelOpts(
position="outside",
formatter="{b|{b}: }{c} {per|{d}%} ",
background_color="#eee",
border_color="#aaa",
border_width=1,
border_radius=4,
rich={
"a": {"color": "#999", "lineHeight": 22, "align": "center"},
"abg": {
"backgroundColor": "#e3e3e3",
"width": "100%",
"align": "right",
"height": 22,
"borderRadius": [4, 4, 0, 0],
},
"hr": {
"borderColor": "#aaa",
"width": "100%",
"borderWidth": 0.5,
"height": 0,
},
"b": {"fontSize": 16, "lineHeight": 33},
"per": {
"color": "#eee",
"backgroundColor": "#334455",
"padding": [2, 4],
"borderRadius": 2,
},
},
),
)
pie.render('微信好友性别比例.html')
VisualSexpyechart(getSex("data/wudifriendsalldata.csv"))
"""
author:魏振东
date:20200303
func:数据可视化-饼状图
"""
from pyecharts.charts import Pie
from pyecharts import options as opts
import xlrd
def getSex(filename, num):
lstsex=[]
data = xlrd.open_workbook(filename, 'r', encoding_override='utf-8')
table = data.sheets()[num]
for i in range(1,table.nrows) :
lstsex.append(table.row_values(i)[5])
return lstsex
def VisualSexpyechart(lstsex171,lstsex172):
sex = dict()
s=0
for f in lstsex171:
if f == '男':
sex["男"] = sex.get("男", 0) + 1
elif f == '女':
sex["女"] = sex.get("女", 0) + 1
total171 = len(lstsex171)
attr = ['171男生', '171女生']
value = [sex["男"], sex["女"]]
list171 = [list(z) for z in zip(attr,value)]
sex1 = dict()
for f in lstsex172:
if f == '男':
sex1["男"] = sex1.get("男", 0) + 1
elif f == '女':
sex1["女"] = sex1.get("女", 0) + 1
total172 = len(lstsex172)
attr1 = ['172男生', '172女生']
value1 = [sex1["男"], sex1["女"]]
list172 = [list(z) for z in zip(attr1,value1)]
init_opts = opts.InitOpts(page_title="171-172男女比例饼状图")
pie = Pie(init_opts=init_opts)
title = opts.TitleOpts(title="171-172男女比例饼状图",
subtitle="171班总人数{0} 172班总人数{1}".format(total171,total172),
pos_left='center')
legend_opts = opts.LegendOpts(orient="vertical",
pos_top="20%",
pos_left="15%")
toolbox_opts = opts.ToolboxOpts(orient="vertical",
pos_top="25%",
pos_right="15%"
)
pie.set_global_opts(title_opts=title,
legend_opts=legend_opts,
toolbox_opts=toolbox_opts
)
pie.add("",
list171,
radius=[0, 75],
center=['50%', '30%'],
rosetype="radius",
label_opts=opts.LabelOpts(formatter="{b}:{c} ")
)
pie.add("",
list172,
radius=[30, 75],
center=['50%', '70%'],
rosetype="area",
label_opts=opts.LabelOpts(
position="outside",
formatter="{b|{b}: }{c} {per|{d}%} ",
background_color="#eee",
border_color="#aaa",
border_width=1,
border_radius=4,
rich={
"a": {"color": "#999", "lineHeight": 22, "align": "center"},
"abg": {
"backgroundColor": "#e3e3e3",
"width": "100%",
"align": "right",
"height": 22,
"borderRadius": [4, 4, 0, 0],
},
"hr": {
"borderColor": "#aaa",
"width": "100%",
"borderWidth": 0.5,
"height": 0,
},
"b": {"fontSize": 16, "lineHeight": 33},
"per": {
"color": "#eee",
"backgroundColor": "#334455",
"padding": [2, 4],
"borderRadius": 2,
},
},
),
)
pie.render('171-172男女比例饼状图.html')
VisualSexpyechart(getSex('../data/软件17学生详细名单.xls',0),getSex('../data/软件17学生详细名单.xls',1))