import json import os from pyecharts import options as opts from pyecharts.charts import Bar, Line from pyecharts.globals import CurrentConfig # 配置使用自定义的ECharts路径 CurrentConfig.ONLINE_HOST = "https://gcore.jsdelivr.net/npm/echarts@6.0.0/dist/" class RenkouModel: @staticmethod def load_population_data(): try: # 获取当前文件所在目录的父目录,然后找到Data文件夹 current_dir = os.path.dirname(os.path.abspath(__file__)) project_root = os.path.dirname(current_dir) # 修正路径计算,只需要上一级目录 data_path = os.path.join(project_root, "Data", "RenKou.json") with open(data_path, "r", encoding="utf-8") as f: data = json.load(f) return data except Exception as e: print(f"读取人口数据出错: {e}") return [] @staticmethod def generate_population_chart_config(year="2024"): # 加载人口数据 population_data = RenkouModel.load_population_data() # 筛选出州市级数据 cities = [item for item in population_data if len(item["area_code"]) == 9 and item["area_code"].endswith("000") and item["area_code"][4:6] == "00" and item["area_code"][2:8] != "000000"] # 提取城市名称和人口数据 city_names = [city["area_name"] for city in cities] total_populations = [city["total_population"].get(year, 0) for city in cities] urban_populations = [city["urban_population"].get(year, 0) for city in cities] rural_populations = [city["rural_population"].get(year, 0) for city in cities] # 创建柱状图 c = ( Bar() .add_xaxis(city_names) .add_yaxis("总人口", total_populations, stack="stack1") .add_yaxis("城镇人口", urban_populations, stack="stack1") .add_yaxis("农村人口", rural_populations, stack="stack1") .set_global_opts( title_opts=opts.TitleOpts( title=f"云南省各州市人口分布图({year}年)", pos_top="1%", pos_left="center" ), tooltip_opts=opts.TooltipOpts( trigger="axis", axis_pointer_type="shadow" ), legend_opts=opts.LegendOpts( pos_top="8%", pos_right="5%" ), datazoom_opts=[opts.DataZoomOpts()], xaxis_opts=opts.AxisOpts( axislabel_opts=opts.LabelOpts(rotate=45) ), yaxis_opts=opts.AxisOpts( name="人口数量(万人)", name_location="middle", name_gap=40 ) ) .set_series_opts( label_opts=opts.LabelOpts(is_show=False), markline_opts=opts.MarkLineOpts( data=[opts.MarkLineItem(type_="average", name="平均值")] ) ) ) # 获取图表的选项配置 options_str = c.dump_options_with_quotes() return json.loads(options_str) @staticmethod def generate_urbanization_rate_chart_config(): # 加载人口数据 population_data = RenkouModel.load_population_data() # 筛选出州市级数据 cities = [item for item in population_data if len(item["area_code"]) == 9 and item["area_code"].endswith("000") and item["area_code"][4:6] == "00" and item["area_code"][2:8] != "000000"] # 提取城市名称 city_names = [city["area_name"] for city in cities] # 创建折线图 line = ( Line() .add_xaxis(city_names) ) # 添加各年份的城镇化率数据 years = ["2020", "2021", "2022", "2023", "2024"] for year in years: urbanization_rates = [city["urbanization_rate"].get(year, 0) for city in cities] line.add_yaxis(f"{year}年", urbanization_rates, markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max")])) line.set_global_opts( title_opts=opts.TitleOpts( title="云南省各州市城镇化率变化趋势", pos_top="1%", pos_left="center" ), tooltip_opts=opts.TooltipOpts(trigger="axis"), legend_opts=opts.LegendOpts( pos_top="8%", pos_right="5%" ), datazoom_opts=[opts.DataZoomOpts()], xaxis_opts=opts.AxisOpts( axislabel_opts=opts.LabelOpts(rotate=45) ), yaxis_opts=opts.AxisOpts( name="城镇化率(%)", name_location="middle", name_gap=40, min_=0, max_=100 ) ) # 获取图表的选项配置 options_str = line.dump_options_with_quotes() return json.loads(options_str)