食用指南

<p style="color:#D35400">本页不能兼容全部移动端设备,请尽量使用桌面版或或者大屏设备访问。</p>

数据介绍:中国各地区(除港澳台)在1961~2014期间建立的污水处理厂的信息,具体信息包括:污水处理厂名称、地理位置、设计规模,现运行规模、处理工艺,以及建厂日期。

数据来源:某政府网站公开数据。

数据前期处理

PDF转Excel

采用Abode Acrobat即可将PDF转换为Excel文件。

Excel转JSON

利用Pythonopenpyxljson模块完成数据的读取、转化、保存。

代码:

# -*- coding:utf-8 -*-
# Author: Man Yacan
# Email: myxc@live.cn
# Website: https://www.manyacan.com
# Datetime: 2020/9/6 11:10
# Software: PyCharm

import json  # 导入json模块
from openpyxl import load_workbook  # 加载Excel处理模块

wb = load_workbook(filename='originalInfo/info.xlsx')  # 打开Excel文件

worksheet = wb['sheet_01']  # 选择工作表

table_header = worksheet['1']  # 得到json数据的keys

project_list = list(worksheet.rows)  # 得到所有行

del project_list[0]  # 去掉标题行(第一行)

json_file = open('Info.json', 'a', encoding='utf-8')  # 设置打开格式,防止保存后乱码

for project in project_list:  # 遍历所有行
    temp_dict = {}
    for index, cell in enumerate(project):
        key = table_header[index].value  # 得到json数据的key值
        temp_dict[key] = cell.value  # 得到json数据的value

    json_data = json.dumps(temp_dict, ensure_ascii=False) + ',\n'  # json格式化
    json_file.write(json_data)  # 写入json数据

json_file.close()  # 关闭json文件

转为json文件后的数据结构为:

[
  {
    "id": 1,
    "province": "北京",
    "city": "朝阳区",
    "name": "高碑店污水处理厂",
    "method": "活性污泥法",
    "startTime": "1993年12月",
    "capability": 100,
    "averageAbility": 93.02
  },
    ....
    ....
    ....
]

注意:污水处理厂的设计能力capability和平均运行能力averageAbility的单位都是万立方米/天

数据可视化

表格数据展示

全国树状图展示

时间变化

各省份现有污水处理厂对比

# -*- coding:utf-8 -*-
# Author: Man Yacan
# Email: myxc@live.cn
# Website: https://www.manyacan.com
# Datetime: 2020/9/6 11:46
# Software: PyCharm

from pyecharts import charts, options, globals  # 可视化处理模块
import json  # 处理json文件模块

with open("originalInfo/Info.json", "r", encoding="utf-8") as f:
    all_info_list = json.load(f)  # 将读取的json文件以list的形式传递进本程序

all_city = [item.get("province") for item in all_info_list]  # 获取所有城市名

# 创建一个数组,用于保存本次数据可视化的数据
# 格式为:[('天津‘, 200), (’河南‘, 300), ('省份名称',污水处理厂数量) ...]
city_data = []
for city in set(all_city):
    city_data.append((city, all_city.count(city)))

# 计算全国省份污水处理厂的平均数量
# average_num = sum([item[1] for item in city_data]) / len(city_data)

bar = charts.Bar(init_opts=options.InitOpts(  # 创建条形统计图类
    width='100%',  # 设置图形宽度
    theme=globals.ThemeType.LIGHT,  # 设置图形主题
    animation_opts=options.AnimationOpts(  # 设置图形动画
        animation_delay=1000, animation_easing="elasticOut"
    )
))  # 创建一个柱形图对象并在创建时启用一个主题

bar.add_xaxis([item[0] for item in city_data])  # 给柱形图设置X列

bar.add_yaxis(
    "中国城镇污水处理厂",
    [item[1] for item in city_data],
    category_gap=2  # 设置图之间的分隔距离
)  # 给柱形图设置Y列

bar.set_global_opts(
    title_opts=options.TitleOpts(title="中国污水处理厂数据可视化", subtitle="各省份污水处理厂对比"),  # 设置图名
    yaxis_opts=options.AxisOpts(name="污水处理厂数量/座"),  # 设置Y轴名称
    xaxis_opts=options.AxisOpts(
        name="省份",  # 设置X轴名称
        axislabel_opts=options.LabelOpts(  # x轴标签的设置
            font_size=10,
            rotate=45,
            horizontal_align='center',
            margin=20
        )
    ),
    datazoom_opts=options.DataZoomOpts(orient="vertical"),  # 设置缩放
    toolbox_opts=options.ToolboxOpts()  # 设置工具条可见
)  # 给柱形图设置标题

bar.set_series_opts(  # 额外的一些设置
    label_opts=options.LabelOpts(is_show=False),  # 设置条状图上的数据不显示
    markline_opts=options.MarkLineOpts(  # 设置标记线
        data=[
            options.MarkLineItem(type_="min", name="最小值"),
            options.MarkLineItem(type_="max", name="最大值"),
            options.MarkLineItem(type_="average", name="平均值")
        ]
    ),
)

bar.render("bar-chart.html")  # 保存为html文件

地图分布

from pyecharts import options as opts
from pyecharts.charts import Geo

import json  # 处理json文件模块

with open("originalInfo/Info.json", "r", encoding="utf-8") as f:
    all_info_list = json.load(f)  # 将读取的json文件以list的形式传递进本程序

all_city = [item.get("city") for item in all_info_list]  # 获取所有城市名

# 创建一个数组,用于保存本次数据可视化的数据
# 格式为:[('天津‘, 200), (’河南‘, 300), ('省份名称',污水处理厂数量) ...]
city_data = []
for city in set(all_city):
    city_data.append((city, all_city.count(city)))

undefined_name = ['兵团', '伊犁州', '黔东南州', '北部新区', '延边州', '农垦总局', '农十师', '农六师', '黔西南州', '农八师', '农十三师', '长白山管委会', '黔南州',
                  '克孜勒苏州', '农一师', '湘西州', '克孜勒苏州']  # 过滤删除不兼容的地名

for index, item in enumerate(city_data):
    if item[0] in undefined_name:
        del city_data[index]

c = (
    Geo()
        .add_schema(maptype="china")
        .add(
        "中国各省份污水处理厂分布",
        city_data,
        type_='effectScatter',
    )
        .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
        .set_global_opts(
        visualmap_opts=opts.VisualMapOpts(), title_opts=opts.TitleOpts(title="中国污水处理厂数据可视化")
    )
        .render("geo_china.html")
)

历年增长

随着我国经济实力(GDP)的增长,污水处理会越来越受到国家和人民的关注。

# -*- coding:utf-8 -*-
# Author: Man Yacan
# Email: myxc@live.cn
# Website: https://www.manyacan.com
# Datetime: 2020/9/6 14:52
# Software: PyCharm

from pyecharts import charts, options, globals  # 可视化处理模块
import json  # 处理json文件模块
import re  # 导入正则处理模块

with open("originalInfo/Info.json", "r", encoding="utf-8") as f:
    all_info_list = json.load(f)  # 将读取的json文件以list的形式传递进本程序

temp_year = [item.get("startTime") for item in all_info_list]  # 获取所有时间

for index, year in enumerate(temp_year):  # 处具体的时间中提取年份
    temp_year[index] = re.match('\d{4}', year).group()

gdp = [1232.34, 5373.35, 6020.92, 7278.5, 9098.95, 10376.15, 12174.59, 15180.39, 12174.59, 15180.39, 17179.74, 18872.87,
       22005.63, 27194.53, 35673.23, 48637.45, 61339.89, 71813.63, 79715.04, 85195.51, 90564.38, 100280.14, 110863.12,
       121717.42, 187318.9, 219438.47, 270092.32, 319244.61, 348517.74, 412119.26, 487940.18, 538579.95, 592963.23,
       641280.57]  # GDP数据

year_data = []
for year in set(temp_year):
    year_data.append((int(year), temp_year.count(year)))

year_data.sort()  # 对年份排序
# print(year_data)

colors = ["#1abc9c", "#3498db", "#d68910"]  # 定义一个颜色list

# 不知道为啥?折线图中的x轴数据只能为字符串类型,其他类型不显示
x_data = [str(item[0]) for item in year_data]
y_data = [item[1] for item in year_data]

bar = charts.Bar(init_opts=options.InitOpts(  # 创建条形统计图类
    width='100%',  # 设置图形宽度
    theme=globals.ThemeType.LIGHT,  # 设置图形主题
    animation_opts=options.AnimationOpts(  # 设置图形动画
        animation_delay=1000, animation_easing="elasticOut"
    )
))  # 创建一个柱形图对象并在创建时启用一个主题

bar.add_xaxis(xaxis_data=x_data)  # 添加X轴数据

bar.add_yaxis(
    series_name='污水处理厂数量/座',
    y_axis=y_data,
    color=colors[1],
    label_opts=options.LabelOpts(is_show=False),
)  # 给柱形图设置Y列

bar.extend_axis(  # 给统计图添加一个额外的列用来作为GDP的Y列
    yaxis=options.AxisOpts(
        name="GDP(亿元)",
        type_="value",
        # axislabel_opts=options.LabelOpts(formatter="{value}亿元"),
    )
)

bar.set_global_opts(
    title_opts=options.TitleOpts(title="中国污水处理厂数据可视化", subtitle="历年增长数据"),  # 设置图名
    yaxis_opts=options.AxisOpts(
        name="污水处理厂数量/座",
        type_="value",
        name_location='center',
        name_rotate=90,
        name_gap=40,
        axistick_opts=options.AxisTickOpts(is_show=True),
        splitline_opts=options.SplitLineOpts(is_show=True),
        # axislabel_opts=options.LabelOpts(formatter="{value} 座"),
    ),  # 设置Y轴名称
    xaxis_opts=options.AxisOpts(
        name="年份",  # 设置X轴名称
        type_="category",
        name_location='center',
        name_gap=40,
        axislabel_opts=options.LabelOpts(  # x轴标签的设置
            font_size=10,
            rotate=45,
            horizontal_align='center',
            margin=20
        ),
        axispointer_opts=options.AxisPointerOpts(is_show=True, type_="shadow")
    ),
    tooltip_opts=options.TooltipOpts(  # 提示工具
        is_show=True, trigger="axis", axis_pointer_type="cross"
    ),
    datazoom_opts=options.DataZoomOpts(pos_bottom='0px'),  # 设置缩放
    # toolbox_opts=options.ToolboxOpts()  # 设置工具条可见
)  # 给柱形图设置标题

bar.set_series_opts(  # 额外的一些设置
    markline_opts=options.MarkLineOpts(  # 设置标记线
        data=[options.MarkLineItem(type_="average", name="平均值")]
    ),
)


# 绘制GDP折线图
line = charts.Line()
line.add_xaxis(xaxis_data=x_data)
line.add_yaxis(
    series_name="历年GDP",
    yaxis_index=1,  # 使用坐标轴的哪个Y轴
    y_axis=gdp,
    label_opts=options.LabelOpts(is_show=False),
    is_smooth=True,
    linestyle_opts=options.LineStyleOpts(
        width=5,
        type_='dotted',
        color=colors[2]
    ),
)

bar.overlap(line).render("bar_02.html")

处理工艺

不难看出,氧化沟、SBR、A2/O是我国污水处理的主流工艺。

# -*- coding:utf-8 -*-
# Author: Man Yacan
# Email: myxc@live.cn
# Website: https://www.manyacan.com
# Datetime: 2020/9/6 18:07
# Software: PyCharm

import json

from pyecharts import options as opts
from pyecharts.charts import WordCloud

with open("originalInfo/Info.json", "r", encoding="utf-8") as f:
    all_info_list = json.load(f)  # 将读取的json文件以list的形式传递进本程序

all_method = []
for item in all_info_list:
    all_method.append(item['method'])

method_data = []
for item in set(all_method):
    method_data.append((item, all_method.count(item)))

# print(method_data)

wordcloud = WordCloud()
wordcloud.add(
    "",
    method_data,
    word_size_range=[20, 100],
    # shape='diamond',
    textstyle_opts=opts.TextStyleOpts(font_family="cursive"),
)
wordcloud.set_global_opts(
    title_opts=opts.TitleOpts(
        title="中国污水处理厂数据可视化",
        title_textstyle_opts=opts.TextStyleOpts(font_size=23),
        subtitle="处理工艺"),  # 设置图名
    tooltip_opts=opts.TooltipOpts(is_show=True)
)
wordcloud.render("wordcloud.html")

动态展示

# -*- coding:utf-8 -*-
# Author: Man Yacan
# Email: myxc@live.cn
# Website: https://www.manyacan.com
# Datetime: 2020/9/12 17:51
# Software: PyCharm

import pandas as pd
from pyecharts.charts import Bar, Timeline
from pyecharts import options, globals
from pyecharts.commons.utils import JsCode
import re


class VisualSewage(object):
    json_file_path = './info.json'

    def __init__(self):
        self.data_frame = self.read_json()

    def run(self):
        """
            类或对象入口函数
        """
        if not self.data_frame.empty:  # 当json文件不为空时,开始制作图形
            print("读取文件成功!")
            self.make_bar()

    def make_timeline(self):
        time_line = Timeline(
            init_opts=options.InitOpts(  # 创建条形统计图类
                width='100%',  # 设置图形宽度,配合tab类使用时不能设置为100%自适应
                theme=globals.ThemeType.LIGHT,  # 设置图形主题
                animation_opts=options.AnimationOpts(  # 设置图形动画
                    animation_delay=1000, animation_easing="elasticOut"
                )
            )
        ).add_schema(
            is_auto_play=True,  # 自动播放
            play_interval=500,  # 播放速度(毫秒)
        )

        return time_line
        # ...

    def make_bar(self):
        """
            制作一个带有时间轴的Bar图
            保存文件名:bar-with-timeline.html
        """
        # 获取json文件的startTime列,从中获取年份1998,2003,2004...,并将此赋为一个新列添加到 data_frame
        self.data_frame['years'] = [int(re.match('\d{4}', item).group()) for item in
                                    self.data_frame["startTime"].tolist()]

        # 实例化时间轴对象
        timeline = self.make_timeline()

        for year in self.data_frame['years'].sort_values().unique():  # 遍历所有年份(无重复)
            # 获取1961至本年份(year)的全部数据
            temp_data = self.data_frame[self.data_frame['years'] <= int(year)]

            # 分组聚合:按省份名称进行分组,求和各省总设计规模
            paint_data = temp_data.groupby(["province"], as_index=False)["capability"].sum()

            # 实例化Bar类
            bar = Bar()
            bar.add_xaxis(paint_data["province"].tolist())  # 添加X轴数据
            bar.add_yaxis(
                f"{year}年中国各省污水处理量(万吨·天)",  # Y轴数据名称
                [round(i, 2) for i in paint_data['capability'].tolist()],  # Y轴数据,这里有个BUG,使用tolist()方法后会产生很多位小数
                markpoint_opts=options.MarkPointOpts(  # 标记最大值点
                    data=[options.MarkPointItem(
                        name="最大值",
                        type_="max",
                        # coord=[x_data[max_id], y_data[max_id]],
                        # value=f"{y_data[max_id]}万吨/天",
                        # symbol='diamond'   # 设置形状
                    )],
                ),
            )
            bar.set_global_opts(
                title_opts=options.TitleOpts("1961年~{}年各省设计规模总和".format(year)),
                graphic_opts=[
                    options.GraphicGroup(
                        graphic_item=options.GraphicItem(
                            rotation=JsCode("Math.PI / 4"),
                            bounding="raw",
                            right=100,
                            bottom=110,
                            z=100,
                        ),
                        children=[
                            options.GraphicRect(
                                graphic_item=options.GraphicItem(
                                    left="center", top="center", z=100
                                ),
                                graphic_shape_opts=options.GraphicShapeOpts(
                                    width=400, height=50
                                ),
                                graphic_basicstyle_opts=options.GraphicBasicStyleOpts(
                                    fill="rgba(0,0,0,0.3)"
                                ),
                            ),
                            options.GraphicText(
                                graphic_item=options.GraphicItem(
                                    left="center", top="center", z=100
                                ),
                                graphic_textstyle_opts=options.GraphicTextStyleOpts(
                                    text="由www.manyacan.com制作",
                                    font="bold 20px Microsoft YaHei",
                                    graphic_basicstyle_opts=options.GraphicBasicStyleOpts(
                                        fill="#fff"
                                    ),
                                ),
                            ),
                        ],
                    )
                ],
                xaxis_opts=options.AxisOpts(  # 自定义X轴标签
                    name="省份",  # 设置X轴名称
                    type_="category",
                    name_location='end',
                    name_gap=10,  # 坐标轴名称与轴线之间的距离。
                    axislabel_opts=options.LabelOpts(  # x轴标签的设置
                        horizontal_align='center',
                        position='top'
                    ),
                    axispointer_opts=options.AxisPointerOpts(is_show=True, type_="line")  # 坐标轴指示器
                ),
                yaxis_opts=options.AxisOpts(  # 自定义Y轴标签
                    name="在运行污水处理厂设计规模综合(万吨/天)",  # 设置Y轴名称
                    name_location='center',  # Y轴名字的位置
                    name_gap=50,  # 坐标轴名称与轴线之间的距离。
                    axispointer_opts=options.AxisPointerOpts(is_show=True, type_="line")  # 坐标轴指示器
                ),
            )

            bar.set_series_opts(  # 额外的一些设置
                label_opts=options.LabelOpts(is_show=False),  # 设置条状图上的数据不显示
                markline_opts=options.MarkLineOpts(  # 设置标记线
                    data=[
                        options.MarkLineItem(type_="min", name="最小值"),
                        options.MarkLineItem(type_="max", name="最大值"),
                        options.MarkLineItem(type_="average", name="平均值")
                    ]
                ),
            )

            timeline.add(bar, f"{year}年")

        timeline.render("bar-with-timeline.html")

    def read_json(self):
        """
            读取json文件
            return DataFrame or None
        """
        try:
            return pd.read_json(self.json_file_path)
        except Exception as e:
            print("读取json文件错误!")
            print(f"文件路径:{self.json_file_path}")
            print(f"错误信息:{e}")
            return pd.DataFrame()


if __name__ == "__main__":
    obj = VisualSewage()
    obj.run()

图片浏览

各省份现有污水处理厂对比
各省份现有污水处理厂对比
历年增长数据
历年增长数据
处理工艺词云
处理工艺词云
地图分布
地图分布