本章节,我们会使用全国空气质量数据呈现中国地图,还会使用全球各个国家或地区GDP数据绘制全球地图。
全国空气质量分布图
数据准备
代码语言:javascript复制import pandas as pd
import numpy as np
path = "final_data02.csv"
show_data = pd.read_csv(path)
show_data.head()
代码语言:javascript复制temp = show_data[['AQI', 'PM2.5细颗粒物',
'PM10可吸入颗粒物', 'CO一氧化碳', 'NO2二氧化氮',
'O3臭氧1小时平均', 'O3臭氧8小时平均', 'SO2二氧化硫']].head(50)
temp.mean()
#
AQI 58.50
PM2.5细颗粒物 36.24
PM10可吸入颗粒物 55.98
CO一氧化碳 0.79
NO2二氧化氮 21.46
O3臭氧1小时平均 56.08
O3臭氧8小时平均 41.98
SO2二氧化硫 16.08
dtype: float64
代码语言:javascript复制show_data['time'] = pd.to_datetime(show_data['time'])
show_data['year'] = show_data.time.dt.year
show_data2 = show_data[show_data['year'] ==2021]
grouper = pd.Grouper(key="time", freq="D")
def transfor(x_df):
# 每一组又分了5个子子组
return x_df.groupby(grouper).mean()
show_data3 = show_data2[['city', 'time', 'AQI', 'PM2.5细颗粒物',
'PM10可吸入颗粒物', 'CO一氧化碳', 'NO2二氧化氮',
'O3臭氧1小时平均', 'O3臭氧8小时平均', 'SO2二氧化硫']]
.groupby("city").apply(transfor) # 10组
show_data3 = show_data3.reset_index()
需求1 展现数据集中各个城市或者地区的空气质量分布
数据中包含了很多城市,我们可以使用地图来展现对应数据,新的一个图表,但是有了前置的基础知识,地图绘制也会变得很容易,我们可以参考官网提供的案例进行预览与绘制。
代码语言:javascript复制from pyecharts import options as opts
from pyecharts.charts import Map
from pyecharts.faker import Faker
c = (
Map()
.add("商家A", [list(z) for z in zip(Faker.provinces, Faker.values())], "china")
.set_global_opts(title_opts=opts.TitleOpts(title="Map-基本示例"))
)
c.render_notebook()
这是一个空的地图,并没有显示数据,这个也是Pyecharts的Bug所在,他并没有及时更新这个数据:
代码语言:javascript复制[list(z) for z in zip(Faker.provinces, Faker.values())]
#
[['广东', 31],
['北京', 60],
['上海', 59],
['江西', 89],
['湖南', 29],
['浙江', 63],
['江苏', 97]]
代码语言:javascript复制show_temp = [['广东省', 74],
['北京市', 86],
['上海市', 123],
['山东省', 199],
['湖南省', 124],
['浙江省', 33],
['江苏省', 91]]
c = (
Map()
.add("商家A",show_temp , "china")
.set_global_opts(
title_opts=opts.TitleOpts(title="Map-VisualMap(连续型)"),
visualmap_opts=opts.VisualMapOpts(max_=200),
)
)
c.render_notebook()
省市名称不能使用简称,必须加上省或者市的后缀,还有一点,这个图表是省份地图,我们需要城市地图, → 离开吧,你需要更广阔的世界
代码语言:javascript复制from pyecharts import options as opts
from pyecharts.charts import Map
from pyecharts.faker import Faker
show_temp = [['济南市', 74],
['青岛市', 86],
['淄博市', 123],
['烟台市', 199],
['威海市', 124]
]
c = (
Map()
.add(
"商家A",
show_temp,
"china-cities",
label_opts=opts.LabelOpts(is_show=False),
is_roam=False
)
.set_global_opts(
title_opts=opts.TitleOpts(title="Map-中国地图(带城市)"),
visualmap_opts=opts.VisualMapOpts(),
)
)
c.render_notebook()
城市数据已经标记出来了,我们可以查看一下数据的结构
代码语言:javascript复制[list(z) for z in zip(Faker.guangdong_city, Faker.values())]
#
[['汕头市', 117],
['汕尾市', 65],
['揭阳市', 28],
['阳江市', 131],
['肇庆市', 104],
['广州市', 27],
['惠州市', 66]]
不出所料,我们需要添加城市完整名称, 我们发现所有的两张地图的差别就是add方法的第三个参数,那么地图中到底支持哪些地区呢?pyecharts支持的数据存放在pyecharts.datasets.map_filenames.json 中,大家可以在 这里进行预览,json文件中的所有key就是地图类型,比如可以查看一个省的地图,就拿我的家乡来说吧
代码语言:javascript复制from pyecharts import options as opts
from pyecharts.charts import Map
from pyecharts.faker import Faker
show_temp = [['赤峰市', 74],
['通辽市', 86],
['呼和浩特', 123],
['包头市', 35]]
c = (
Map()
.add(
"商家A",
show_temp,
"内蒙古",
label_opts=opts.LabelOpts(is_show=False),
is_roam=False
)
.set_global_opts(
title_opts=opts.TitleOpts(title="Map-中国地图(带城市)"),
visualmap_opts=opts.VisualMapOpts(),
)
)
c.render_notebook()
回归正题,我们还是要使用全国城市地图,进行空气质量分局地图的绘制,中国城市地图支持的城市名称我已经整理出来了
代码语言:javascript复制china_cities = "石家庄市,唐山市,秦皇岛市,邯郸市,邢台市,保定市,张家口市,承德市,沧州市,廊坊市,衡水市,太原市,大同市,阳泉市,长治市,晋城市,朔州市,晋中市,运城市,忻州市,临汾市,吕梁市,呼和浩特市,包头市,乌海市,赤峰市,通辽市,鄂尔多斯市,呼伦贝尔市,巴彦淖尔市,乌兰察布市,兴安盟,锡林郭勒盟,阿拉善盟,沈阳市,大连市,鞍山市,抚顺市,本溪市,丹东市,锦州市,营口市,阜新市,辽阳市,盘锦市,铁岭市,朝阳市,葫芦岛市,长春市,吉林市,四平市,辽源市,通化市,白山市,松原市,白城市,延边朝鲜族自治州,哈尔滨市,齐齐哈尔市,鸡西市,鹤岗市,双鸭山市,大庆市,伊春市,佳木斯市,七台河市,牡丹江市,黑河市,绥化市,大兴安岭地区,南京市,无锡市,徐州市,常州市,苏州市,南通市,连云港市,淮安市,盐城市,扬州市,镇江市,泰州市,宿迁市,杭州市,宁波市,温州市,嘉兴市,湖州市,绍兴市,金华市,衢州市,舟山市,台州市,丽水市,合肥市,芜湖市,蚌埠市,淮南市,马鞍山市,淮北市,铜陵市,安庆市,黄山市,滁州市,阜阳市,宿州市,六安市,亳州市,池州市,宣城市,福州市,厦门市,莆田市,三明市,泉州市,漳州市,南平市,龙岩市,宁德市,南昌市,景德镇市,萍乡市,九江市,新余市,鹰潭市,赣州市,吉安市,宜春市,抚州市,上饶市,济南市,青岛市,淄博市,枣庄市,东营市,烟台市,潍坊市,济宁市,泰安市,威海市,日照市,临沂市,德州市,聊城市,滨州市,菏泽市,郑州市,开封市,洛阳市,平顶山市,安阳市,鹤壁市,新乡市,焦作市,濮阳市,许昌市,漯河市,三门峡市,南阳市,商丘市,信阳市,周口市,驻马店市,济源市,武汉市,黄石市,十堰市,宜昌市,襄阳市,鄂州市,荆门市,孝感市,荆州市,黄冈市,咸宁市,随州市,恩施土家族苗族自治州,仙桃市,潜江市,天门市,神农架林区,长沙市,株洲市,湘潭市,衡阳市,邵阳市,岳阳市,常德市,张家界市,益阳市,郴州市,永州市,怀化市,娄底市,湘西土家族苗族自治州,广州市,韶关市,深圳市,珠海市,汕头市,佛山市,江门市,湛江市,茂名市,肇庆市,惠州市,梅州市,汕尾市,河源市,阳江市,清远市,东莞市,中山市,潮州市,揭阳市,云浮市,南宁市,柳州市,桂林市,梧州市,北海市,防城港市,钦州市,贵港市,玉林市,百色市,贺州市,河池市,来宾市,崇左市,海口市,三亚市,三沙市,儋州市,五指山市,琼海市,文昌市,万宁市,东方市,定安县,屯昌县,澄迈县,临高县,白沙黎族自治县,昌江黎族自治县,乐东黎族自治县,陵水黎族自治县,保亭黎族苗族自治县,琼中黎族苗族自治县,成都市,自贡市,攀枝花市,泸州市,德阳市,绵阳市,广元市,遂宁市,内江市,乐山市,南充市,眉山市,宜宾市,广安市,达州市,雅安市,巴中市,资阳市,阿坝藏族羌族自治州,甘孜藏族自治州,凉山彝族自治州,贵阳市,六盘水市,遵义市,安顺市,毕节市,铜仁市,黔西南布依族苗族自,黔东南苗,黔南布依族苗族自治州,昆明市,曲靖市,玉溪市,保山市,昭通市,丽江市,普洱市,临沧市,楚雄彝族自治州,红河哈尼族彝族自治州,文山壮族苗族自治州,西双版纳傣族自治州,大理白族自治州,德宏傣族景颇族自治州,怒江傈僳族自治州,迪庆藏族自治州,拉萨市,日喀则市,昌都市,林芝市,山南市,那曲市,阿里地区,西安市,铜川市,宝鸡市,咸阳市,渭南市,延安市,汉中市,榆林市,安康市,商洛市,兰州市,嘉峪关市,金昌市,白银市,天水市,武威市,张掖市,平凉市,酒泉市,庆阳市,定西市,陇南市,临夏回族自治州,甘南藏族自治州,西宁市,海东市,海北藏族自治州,黄南藏族自治州,海南藏族自治州,果洛藏族自治州,玉树藏族自治州,海西蒙古族藏族自治州,银川市,石嘴山市,吴忠市,固原市,中卫市,乌鲁木齐市,克拉玛依市,吐鲁番市,哈密市,昌吉回族自治州,博尔塔拉蒙古自治州,巴音郭楞蒙古自治州,阿克苏地区,克孜勒苏柯尔克孜自治州,喀什地区,和田地区,伊犁哈萨克自治州,塔城地区,阿勒泰地区,石河子市,阿拉尔市,图木舒克市,五家渠市,北屯市,铁门关市,双河市,可克达拉市,昆玉市,胡杨河市,北京市,天津市,上海市,重庆市,台湾省,香港特别行政区,澳门特别行政区"
china_cities = china_cities.split(",")
len(china_cities)
代码语言:javascript复制abnormal_data = {
"张家港":"苏州市"
}
def add_city(x):
# 北京 -> 北京市
# 济南 -> 济南市
if abnormal_data.get(x):
return abnormal_data.get(x)
if (x "市") in china_cities:
return x "市"
for normal_city in china_cities:
if len(x[:-1])>=2 and x[:-1] in normal_city:
return normal_city
elif len(x[:-2])>=2 and x[:-2] in normal_city:
return normal_city
return "未知"
show_data3.loc[:,"normal_city"] = show_data3.city.apply(add_city)
这个只是一个简单的处理与映射,我们的核心放在了可视化实现上,在现实的业务中,也不会出现这样的城市数据。
我们编写一个函数,接受指定数据集,指定日期,指定指标,然后将对应的数据使用地图进行绘制。
代码语言:javascript复制def get_per_day_data_show(df, show_date, col_name):
condition_str = f"time=='{show_date}'"
show_data = df.query(condition_str)
c = (
Map()
.add(
""
, [list(z) for z in zip(show_data.normal_city.values.tolist(), show_data[col_name].values.tolist())]
, "china-cities"
)
.set_global_opts(
title_opts=opts.TitleOpts(title="中国空气质量数据可视化")
)
)
return c
这个地图确实已经绘制出来了,但是,数据好像不太清晰,所以,需要重新修改一个配置
代码语言:javascript复制def get_per_day_data_show(df, show_date, col_name):
condition_str = f"time=='{show_date}'"
show_data = df.query(condition_str)
c = (
Map()
.add(
""
, [list(z) for z in zip(show_data.normal_city.values.tolist(), show_data[col_name].values.tolist())]
, "china-cities"
, label_opts=opts.LabelOpts(is_show=False)
, is_roam=False
, is_map_symbol_show=False
, itemstyle_opts=opts.ItemStyleOpts(
border_color = "rgb(0,0,0,0.3)"
)
)
.set_global_opts(
title_opts=opts.TitleOpts(title="中国空气质量数据可视化")
)
)
return c
c = get_per_day_data_show(show_data4_good2,"2021-01-01","AQI")
c.render_notebook()
在Line图中,曾经自定义过对应的tooltip,本次案例需要对原来的模本进行小小的改动,主要是新增了img标签。
代码语言:javascript复制from pyecharts.commons.utils import JsCode
def get_per_day_data_show(df, show_date, col_name):
condition_str = f"time=='{show_date}'"
show_data = df.query(condition_str)
value_max_ = show_data[col_name].max()
value_min_ = show_data[col_name].min()
c = (
Map()
.add(
""
, [list(z) for z in zip(show_data.normal_city.values.tolist(), show_data[col_name].values.tolist())]
, "china-cities"
, label_opts=opts.LabelOpts(is_show=False)
, is_roam=False
, is_map_symbol_show=False
, itemstyle_opts=opts.ItemStyleOpts(
border_color = "rgb(0,0,0,0.3)"
)
, tooltip_opts=opts.TooltipOpts(
formatter=JsCode(
"""
function(param){
if(!param.data){
return;
}
let temp='';
temp = '<div style="width:auto;height:auto; background: ';
temp = choose_color(param.data.value);
temp = ';"><div style="font-size:12px;color:#ffffff;margin-bottom:8px;display:flex;align-items:center;line-height:1;"><span style="flex:1;text-align:left;">';
temp = format_number_value(param);
temp = '</span><div style="display:inline-block;margin-left:8px;border-radius:6px;width:50px;height:40px;background-color:gray"><img src="';
temp = choose_image(param.data.value);
temp ='" style="width: 100%;height: 100%;"></div></div></div>';
return temp;
}
"""
)
)
)
.set_global_opts(
title_opts=opts.TitleOpts(title="中国空气质量数据可视化")
, visualmap_opts=opts.VisualMapOpts(
max_=value_max_ 100
, min_=value_min_
)
, graphic_opts=opts.GraphicGroup(
graphic_item=opts.GraphicItem(
rotation=JsCode("Math.PI / 4"),
bounding="raw",
right=100,
bottom=110,
z=100,
)
, children=[
opts.GraphicRect(
graphic_item=opts.GraphicItem(
left="center", top="center", z=100
)
, graphic_shape_opts=opts.GraphicShapeOpts(
width=400, height=50
)
,graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
fill="rgba(0,0,0,0.3)"
)
)
, opts.GraphicText(
graphic_item=opts.GraphicItem(
left="center", top="center", z=100
),
graphic_textstyle_opts=opts.GraphicTextStyleOpts(
text=show_date
,font="bold 26px Microsoft YaHei"
,graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
fill="#fff"
),
)
)
]
)
)
)
c.add_js_funcs(
f"""
let good_image='{aqi_good}';
let normal_image='{aqi_normal}';
let less_bad_image='{aqi_less_bad}';
let bad_image='{aqi_bad}';
let more_bad_image='{aqi_more_bad}';
let terrible_image='{aqi_terrible}';
"""
)
c.add_js_funcs(
"""
function choose_image(value){
if(value<50){
return good_image;
}else if(value<100){
return normal_image;
}else if(value<150){
return less_bad_image;
}else if(value<200){
return bad_image;
}else if(value<300){
return more_bad_image;
}else{
return terrible_image;
}
};
function format_number_value(param){
return param.data.name ':' Number(param.data.value).toFixed(2)
}
function choose_color(value){
if(value<=50){
return '#97D560';
}else if(value<=100){
return '#FFCF55';
}else if(value<=150){
return '#FF8E52';
}else if(value<=200){
return '#FF5F66';
}else if(value<=300){
return '#A171B2';
}else{
return '#915068';
}
}
"""
)
return c
c = get_per_day_data_show(show_data4_good2,"2021-01-03","AQI")
c.render_notebook()
所以JavaScript对于Pyecharts也是至关重要的,可以绘制更炫彩的图像,
都做到这里了,接下来就让他动起来吧,引入TimeLine
代码语言:javascript复制from pyecharts import options as opts
from pyecharts.charts import Map, Timeline
days = pd.Series(show_data4_good2.time.value_counts().index.astype("str")).sort_values().tolist()
tl = Timeline()
tl.add_schema(
play_interval=1000
, is_auto_play=True
, is_timeline_show=False
)
for day in days:
map0 = get_per_day_data_show(show_data4_good2,day,"AQI")
tl.add(map0, "{}日".format(day))
tl.add_js_funcs(
f"""
let good_image='{aqi_good}';
let normal_image='{aqi_normal}';
let less_bad_image='{aqi_less_bad}';
let bad_image='{aqi_bad}';
let more_bad_image='{aqi_more_bad}';
let terrible_image='{aqi_terrible}';
"""
)
tl.add_js_funcs(
"""
function choose_image(value){
if(value<50){
return good_image;
}else if(value<100){
return normal_image;
}else if(value<150){
return less_bad_image;
}else if(value<200){
return bad_image;
}else if(value<300){
return more_bad_image;
}else{
return terrible_image;
}
};
function format_number_value(param){
return param.data.name ':' Number(param.data.value).toFixed(2)
}
function choose_color(value){
if(value<=50){
return '#97D560';
}else if(value<=100){
return '#FFCF55';
}else if(value<=150){
return '#FF8E52';
}else if(value<=200){
return '#FF5F66';
}else if(value<=300){
return '#A171B2';
}else{
return '#915068';
}
}
"""
)
tl.render_notebook()
# tl.render("./map02.html")
现在图标显示是变化的了,如果对某一天的数据特别感兴趣,你想查看一下,当你鼠标移入图表的时候,你想暂停移动,这个时候,就需要Js交互了,监听移入事件,就是mouseover事件,监听移出事件,就是mouseout事件,但是TimeLine组件,并不能够真正的暂停,只能移入鼠标的时候,将timeline停止,移出的时候从头开始进行播放,但是需求确定是继续播放,所以,需要记录暂停那个时刻播放的时间节点,再次播放时,需要继续跳转到指定的节点。
代码语言:javascript复制from pyecharts import options as opts
from pyecharts.charts import Map, Timeline
days = pd.Series(show_data4_good2.time.value_counts().index.astype("str")).sort_values().tolist()
tl = Timeline(
init_opts=opts.InitOpts(
chart_id="time"
)
)
tl.add_schema(
play_interval=1000
, is_auto_play=True
, is_timeline_show=False
)
for day in days[:10]:
map0 = get_per_day_data_show(show_data4_good2,day,"AQI")
tl.add(map0, "{}日".format(day))
tl.add_js_funcs(
"""
let currentIndex = 0;
chart_time.on("mouseover",(param)=>{
option_time.baseOption.timeline.autoPlay=false;
chart_time.setOption(option_time,true)
chart_time.dispatchAction({type: 'timelineChange',currentIndex: currentIndex})
});
chart_time.on("mouseout",(param)=>{
option_time.baseOption.timeline.autoPlay=true;
chart_time.setOption(option_time,true)
chart_time.dispatchAction({type: 'timelineChange',currentIndex: currentIndex})
});
chart_time.on('timelinechanged',function(timeLineIndex){
currentIndex = timeLineIndex.currentIndex;
})
"""
)
tl.add_js_funcs(
f"""
let good_image='{aqi_good}';
let normal_image='{aqi_normal}';
let less_bad_image='{aqi_less_bad}';
let bad_image='{aqi_bad}';
let more_bad_image='{aqi_more_bad}';
let terrible_image='{aqi_terrible}';
"""
)
tl.add_js_funcs(
"""
function choose_image(value){
if(value<50){
return good_image;
}else if(value<100){
return normal_image;
}else if(value<150){
return less_bad_image;
}else if(value<200){
return bad_image;
}else if(value<300){
return more_bad_image;
}else{
return terrible_image;
}
};
function format_number_value(param){
return param.data.name ':' Number(param.data.value).toFixed(2)
}
function choose_color(value){
if(value<=50){
return '#97D560';
}else if(value<=100){
return '#FFCF55';
}else if(value<=150){
return '#FF8E52';
}else if(value<=200){
return '#FF5F66';
}else if(value<=300){
return '#A171B2';
}else{
return '#915068';
}
}
"""
)
tl.render()
需求2 展现世界地图,对GDP数据进行展示
首先需要进行数据处理,本数据集包含世界1960年至2021年各个国家或者地区GDP数值分布,根据之前的经验,数据处理难点还是在国家编号编码处理这里,本实验提供了countries.json文件,该文件中返回地图中需要的标准的国家或地区名称。
代码语言:javascript复制gdp_path = "./gdp/gdp_clean.csv"
gdp_growth_path = "./gdp/gdp_growth.csv"
pd.set_option('display.float_format', lambda x: '%.2f' % x)
gdp_all = pd.read_csv(gdp_path)
加载countries.json文件
代码语言:javascript复制import json
counties_json = "./gdp/countries.json"
counties_json_str = ""
with open(counties_json,'r') as f:
counties_json_str = f.read()
counties = json.loads(counties_json_str)
def transfer(code):
en_name = ""
for obj in counties:
if obj['iso3'] == code:
en_name = obj['name']
return en_name
return "未知"
gdp_all['国家或地区英文'] = gdp_all['国家或地区编码'].apply(transfer)
数据处理完毕,接下来就是需要进行可视化,做世界地图也很简答,官方网站也提供了很多的示例,穿越,PiuPiuPiu
代码语言:javascript复制from pyecharts import options as opts
from pyecharts.charts import Map
from pyecharts.faker import Faker
c = (
Map()
.add("商家A", [list(z) for z in zip(Faker.country, Faker.values())], "world", is_roam=False)
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(
title_opts=opts.TitleOpts(title="Map-世界地图"),
visualmap_opts=opts.VisualMapOpts(max_=200),
)
)
c.render_notebook()
只需要替换数据即可
代码语言:javascript复制from pyecharts.charts import Map
from pyecharts import options as opts
from pyecharts.commons.utils import JsCode
c = (
Map()
.add(
"商家A"
, [list(z) for z in zip(gdp_all['国家或地区英文'].tolist()
, gdp_all['2021'].tolist())]
, "world"
, is_map_symbol_show = False
, is_roam=False
)
.set_series_opts(label_opts=opts.LabelOpts(is_show=False)
, tooltip_opts=opts.TooltipOpts(
formatter=JsCode(
"""
function (param){
let show_str = '';
if(param.data.value){
show_str =param.data.name;
show_str =': $' Number(param.data.value).toLocaleString();
return show_str;
}else{
return '';
}
}
"""
)
)
)
.set_global_opts(
title_opts=opts.TitleOpts(title="Map-世界地图"),
visualmap_opts=opts.VisualMapOpts(max_=gdp_all['2021'].max()),
)
)
c.render_notebook()
这个是一个定点时间的数据,如果需要让图像轮播,那么我们还需要按时间处理轮播数据。同时,我这里加上了条主图和饼图分别表示该数据。
代码语言:javascript复制range_color=[
'#abd9e9',
'#e0f3f8',
'#ffffbf',
'#fee090',
'#fdae61',
'#f46d43',
'#d73027',
'#a50026'
]
def chart(x_data, y_data, data_pair, map_data,year):
bar = Bar(init_opts=opts.InitOpts(
theme='light'
))
bar.add_xaxis(
x_data[::-1]
)
bar.add_yaxis(
'',
y_data[::-1],
category_gap='40%',
label_opts=opts.LabelOpts(
is_show=True,
formatter='{c} 亿美元',
position='insideLeft'),
)
bar.set_global_opts(
xaxis_opts=opts.AxisOpts(is_show=False),
yaxis_opts=opts.AxisOpts(
axisline_opts=opts.AxisLineOpts(is_show=False),
axistick_opts=opts.AxisTickOpts(is_show=False)),
title_opts=opts.TitleOpts(
title='GDP TOP20',
pos_left='2%',
pos_top='2%',
title_textstyle_opts=opts.TextStyleOpts(
color='#00BFFF', font_size=20)
),
visualmap_opts=opts.VisualMapOpts(
is_show=False,
max_=(gdp_all['2021']/1e8).max(),
range_color=range_color
, is_piecewise=False
, dimension=0
),
graphic_opts=[
opts.GraphicGroup(graphic_item=opts.GraphicItem(
bounding="raw",
right=200,
bottom=100,
z=100),
# 文字显示区域配置
children=[
# 文本设置
opts.GraphicText(
graphic_item=opts.GraphicItem(
left="center", top="center", z=100
),
graphic_textstyle_opts=opts.GraphicTextStyleOpts(
# 要显示的文本
text='{}年'.format(year),
font="bold 86px Microsoft YaHei",
graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
fill="rgba(0,0,0,.2)"
),
),
),
],
)
]
)
bar.reversal_axis()
pie = Pie(init_opts=opts.InitOpts(theme='light', width='200px', height='200px'))
pie.add(
"",
data_pair,
# 指定饼图中心位置
center=["25%", "75%"],
# 将饼图尺寸相应缩小,不然饼图会重叠
radius=["8%", "18%"],
)
pie.set_global_opts(
legend_opts=opts.LegendOpts(is_show=False),
)
pie.set_colors(range_color)
c = (
Map()
.add("", [list(z) for z in zip(map_data["国家或地区英文"].values.tolist()
, (map_data[year]/1e8).values.tolist())]
, "world"
, is_map_symbol_show=False
, zoom=1
, is_roam=False
)
.set_series_opts(label_opts=opts.LabelOpts(is_show=False)
, tooltip_opts=opts.TooltipOpts(
formatter=JsCode(
"""
function (param){
let show_str = '';
if(param.data){
show_str =param.data.name;
show_str =': $' Number(param.data.value).toLocaleString();
return show_str;
}else{
return '';
}
}
"""
)
)
)
)
grid = Grid(init_opts=opts.InitOpts(theme='light', width='1200px', height='800px'))
bar.overlap(pie)
grid.add(bar, is_control_axis_index=True, grid_opts=opts.GridOpts(pos_left='5%', pos_right='70%', pos_top='50%', pos_bottom='0%'))
grid.add(c, is_control_axis_index=False, grid_opts=opts.GridOpts())
return grid
代码语言:javascript复制from pyecharts.charts import Map, Timeline, Bar, Pie, Grid
gdp_all_countries = gdp_all.query("国家或地区英文 !='未知'")
gdp_all_countries = gdp_all_countries.fillna(0)
gdp_all_countries = gdp_all_countries.set_index("国家或地区")
def datas_year(df, columns):
tl = Timeline(init_opts=opts.InitOpts(width="1000px",height="600px"))
tl.add_schema(
is_auto_play=True
, play_interval=1000
, is_loop_play=False
, is_timeline_show=False
)
for column in columns:
map_show_data = gdp_all_countries[['国家或地区英文',column]]
bar_pie_show_data = map_show_data.sort_values(column,ascending=False).iloc[:20][column]
data_pair, data_x, data_y = [],[],[]
pie_data_index = 0
for name in bar_pie_show_data.index:
data_x.append(name)
if name=='中国':
data_y.append(
opts.BarItem(
name=name
, value=round(bar_pie_show_data[name]/1e8, 0)
, itemstyle_opts={
# 阴影颜色
'shadowColor': 'rgba(255, 0, 0, 0.5)',
'shadowBlur': 20, # 阴影大小
'shadowOffsetY': 5, # Y轴方向阴影偏移
'shadowOffsetX': 5, # x轴方向阴影偏移
'borderColor': 'rgba(255, 0, 0, 1)',
'borderWidth': 3
}
)
)
else:
data_y.append(
opts.BarItem(
name=name,
value=round(bar_pie_show_data[name]/1e8, 0),
itemstyle_opts={
'shadowColor': 'rgba(0, 0, 0, .5)',
'shadowBlur': 5, # 阴影大小
'shadowOffsetY': 2, # Y轴方向阴影偏移
'shadowOffsetX': 2, # x轴方向阴影偏移
'borderColor': '#fff'
}
)
)
if pie_data_index<=4:
data_pair.append(
opts.PieItem(
name=name
, value=round(bar_pie_show_data[name]/1e8, 0)
, label_opts=opts.LabelOpts(
is_show=True, formatter='{b}n{d}%'
)
)
)
else:
data_pair.append(
opts.PieItem(
name=name
, value=round(bar_pie_show_data[name]/1e8, 0)
, label_opts=opts.LabelOpts(
is_show=False, position='inside'
)
)
)
pie_data_index =1
c = chart(data_x,data_y,data_pair,map_show_data,column)
c.load_javascript()
tl.add(c, "{}年".format(column))
return tl
代码语言:javascript复制years = ['1960', '1961', '1962', '1963', '1964', '1965', '1966','1967', '1968', '1969', '1970', '1971', '1972', '1973', '1974', '1975','1976', '1977', '1978', '1979', '1980', '1981', '1982', '1983', '1984','1985', '1986', '1987', '1988', '1989', '1990', '1991', '1992', '1993','1994', '1995', '1996', '1997', '1998', '1999', '2000', '2001', '2002','2003', '2004', '2005', '2006', '2007', '2008', '2009', '2010', '2011','2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020','2021']
tl = datas_year(gdp_all_countries, years)
tl.render_notebook()