├── .gitattributes ├── README.md ├── res ├── GUI界面1.png ├── GUI界面2.png ├── city_line.db ├── city_line.db-journal ├── subway.csv ├── 上海各线路站点数量的分布趋势.png ├── 中国地铁站最爱用的字.html ├── 全国各城市总的换乘站点数量(2换乘、3换乘、4换乘等)分布统计.png ├── 分析各个城市的大学数量与站点数量的关系.png ├── 北京各线路站点数量的分布趋势.png ├── 各个城市的大学数量与站点数量的关系.png ├── 各个城市的站点数量的散点图分布.png ├── 各个城市的站点数量的饼状图分布.png ├── 各个城市的线路数量的饼状图分布.png ├── 各城市各线路的站点数量前10的变化.png ├── 各城市地铁线路数量分布.html ├── 名字中带有大学的地铁站的城市数量分布.png ├── 哈尔滨各线路站点数量的分布趋势.png ├── 地铁名词云.jpg ├── 地铁站最爱用门命名的城市.html ├── 大学数量与站点数量的双变量图.png ├── 天津各线路站点数量的分布趋势.png ├── 已开通地铁城市分布情况.html ├── 广州、天津、武汉、重庆同名的线路1-线路6的站点数量分布.png ├── 武汉各线路站点数量的分布趋势.png ├── 每个城市哪条线路的站点数最多.png └── 郑州、武汉、广州、长沙同名的线路1-线路6的站点数量分布.png └── src ├── Analyse.py ├── Search.py ├── Spider.py ├── bg1.png ├── tree2.jpg └── university.csv /.gitattributes: -------------------------------------------------------------------------------- 1 | *.html linguist-language=python 2 | *.png linguist-language=python 3 | *.jpg linguist-language=python 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 中国城市轨道交通数据可视化分析—Python 4 | ===== 5 | 6 | > - A demo based on data visualized analysis written in Python language. 7 | 8 | 9 | 10 | ## 概述 11 | 12 | > - 本项目是一个基于 Python 的简单数据可视化分析的小Demo。通过这个项目可以练习使用Python数据可视化分析相关的强大的库和模块,练习绘制简单的GUI界面并且连接数据库,更加深了对Python语言的学习和拓展。本项目也可作为学校的大作业、大实验实践或者课程设计等的选题项目。 13 | > - 本项目通过多线程爬虫获取了高德地图中的中国轨道交通的一些数据信息,高德地图这个权威的网站也保证了数据的完整可靠性,然后进行了一些简单并且有趣的数据可视化分析,另外还设计了一个GUI界面,查询数据库或者文件中的一些信息。 14 | > 15 | > - 如发现文档中或者源代码中有错误,欢迎大家在 `Issues` 中研究讨论,欢迎大家 `Fork` 和 `Pull requests` 改善代码,十分感谢! 16 | 17 | ## 使用语言 18 | 19 | - Python 3 20 | 21 | ## 主要技术 22 | 23 | * **网络编程** 24 | * **多线程** 25 | * **文件操作** 26 | * **数据库编程** 27 | * **GUI** 28 | * **数据分析** 29 | 30 | ## 导入的库和模块 31 | ```python 32 | import json 33 | import requests 34 | from bs4 import BeautifulSoup 35 | import sqlite3 36 | import threading 37 | 38 | import tkinter as tk 39 | from tkinter import scrolledtext 40 | 41 | import pandas as pd 42 | from pyecharts import Line, Bar, Geo 43 | import numpy as np 44 | from wordcloud import WordCloud, ImageColorGenerator 45 | import jieba 46 | import matplotlib.pyplot as plt 47 | import seaborn as sns 48 | ``` 49 | 50 | ## 项目整体思路 51 | 52 | 1. 网页分析 53 | 54 | 2. 多线程爬虫爬取信息 55 | 56 | 3. 数据保存至文件中和数据库中 57 | 58 | 4. 利用 tkinter 绘制 GUI 界面,实现查询线路和站点两个功能 59 | 60 | 5. 数据可视化分析 61 | 62 | (1)直接控制台显示分析结果 63 | 64 | (2)绘制中国地图、柱状图等,生成 .html 文件 65 | 66 | (3)绘制词云 67 | 68 | (4)绘制柱状图、饼状图、折线图、散点图、双变量图等,生成 .png 文件 69 | 70 | ## 运行 71 | 72 | - 分别运行`src`文件夹中的`.py`文件即可 73 | 74 | ## 部分运行结果样例 75 | 76 | - `res`文件夹中的文件 77 | 78 | ## 待上传文件 79 | 80 | - [ ] 总结报告.docx,预计5000字左右 81 | - [ ] 答辩演示.ppt,预计20页左右 82 | 83 | 84 | -------------------------------------------------------------------------------- /res/GUI界面1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/GUI界面1.png -------------------------------------------------------------------------------- /res/GUI界面2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/GUI界面2.png -------------------------------------------------------------------------------- /res/city_line.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/city_line.db -------------------------------------------------------------------------------- /res/city_line.db-journal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/city_line.db-journal -------------------------------------------------------------------------------- /res/subway.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/subway.csv -------------------------------------------------------------------------------- /res/上海各线路站点数量的分布趋势.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/上海各线路站点数量的分布趋势.png -------------------------------------------------------------------------------- /res/全国各城市总的换乘站点数量(2换乘、3换乘、4换乘等)分布统计.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/全国各城市总的换乘站点数量(2换乘、3换乘、4换乘等)分布统计.png -------------------------------------------------------------------------------- /res/分析各个城市的大学数量与站点数量的关系.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/分析各个城市的大学数量与站点数量的关系.png -------------------------------------------------------------------------------- /res/北京各线路站点数量的分布趋势.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/北京各线路站点数量的分布趋势.png -------------------------------------------------------------------------------- /res/各个城市的大学数量与站点数量的关系.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/各个城市的大学数量与站点数量的关系.png -------------------------------------------------------------------------------- /res/各个城市的站点数量的散点图分布.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/各个城市的站点数量的散点图分布.png -------------------------------------------------------------------------------- /res/各个城市的站点数量的饼状图分布.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/各个城市的站点数量的饼状图分布.png -------------------------------------------------------------------------------- /res/各个城市的线路数量的饼状图分布.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/各个城市的线路数量的饼状图分布.png -------------------------------------------------------------------------------- /res/各城市各线路的站点数量前10的变化.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/各城市各线路的站点数量前10的变化.png -------------------------------------------------------------------------------- /res/名字中带有大学的地铁站的城市数量分布.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/名字中带有大学的地铁站的城市数量分布.png -------------------------------------------------------------------------------- /res/哈尔滨各线路站点数量的分布趋势.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/哈尔滨各线路站点数量的分布趋势.png -------------------------------------------------------------------------------- /res/地铁名词云.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/地铁名词云.jpg -------------------------------------------------------------------------------- /res/大学数量与站点数量的双变量图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/大学数量与站点数量的双变量图.png -------------------------------------------------------------------------------- /res/天津各线路站点数量的分布趋势.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/天津各线路站点数量的分布趋势.png -------------------------------------------------------------------------------- /res/广州、天津、武汉、重庆同名的线路1-线路6的站点数量分布.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/广州、天津、武汉、重庆同名的线路1-线路6的站点数量分布.png -------------------------------------------------------------------------------- /res/武汉各线路站点数量的分布趋势.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/武汉各线路站点数量的分布趋势.png -------------------------------------------------------------------------------- /res/每个城市哪条线路的站点数最多.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/每个城市哪条线路的站点数最多.png -------------------------------------------------------------------------------- /res/郑州、武汉、广州、长沙同名的线路1-线路6的站点数量分布.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/res/郑州、武汉、广州、长沙同名的线路1-线路6的站点数量分布.png -------------------------------------------------------------------------------- /src/Analyse.py: -------------------------------------------------------------------------------- 1 | from wordcloud import WordCloud, ImageColorGenerator 2 | from pyecharts import Line, Bar, Geo 3 | import matplotlib.pyplot as plt 4 | import pandas as pd 5 | import numpy as np 6 | import jieba 7 | import seaborn as sns 8 | 9 | # 设置列名与数据对齐 10 | pd.set_option('display.unicode.ambiguous_as_wide', True) 11 | pd.set_option('display.unicode.east_asian_width', True) 12 | # 显示10行 13 | pd.set_option('display.max_rows', 10) 14 | # 读取数据 15 | df = pd.read_csv('subway_all.csv', header=None, names=['city', 'line', 'station'], encoding='gbk') 16 | # 各个城市地铁线路情况 17 | df_line = df.groupby(['city', 'line']).count().reset_index() 18 | print(df_line) 19 | 20 | def create_map(df): 21 | # 绘制地图 22 | value = [i for i in df['line']] 23 | attr = [i for i in df['city']] 24 | geo = Geo("已开通地铁城市分布情况", title_pos='center', title_top='0', width=800, height=400, 25 | title_color="#fff", background_color="#404a59", ) 26 | geo.add("", attr, value, is_visualmap=True, visual_range=[0, 25], visual_text_color="#fff", symbol_size=15) 27 | geo.render("已开通地铁城市分布情况.html") 28 | 29 | 30 | def create_line(df): 31 | """ 32 | 生成城市地铁线路数量分布情况 33 | """ 34 | title_len = df['line'] 35 | bins = [0, 5, 10, 15, 20, 25] 36 | level = ['0-5', '5-10', '10-15', '15-20', '20以上'] 37 | len_stage = pd.cut(title_len, bins=bins, labels=level).value_counts().sort_index() 38 | # 生成柱状图 39 | attr = len_stage.index 40 | v1 = len_stage.values 41 | bar = Bar("各城市地铁线路数量分布", title_pos='center', title_top='18', width=800, height=400) 42 | bar.add("", attr, v1, is_stack=True, is_label_show=True) 43 | bar.render("各城市地铁线路数量分布.html") 44 | 45 | 46 | # 各个城市地铁线路数 47 | df_city = df_line.groupby(['city']).count().reset_index().sort_values(by='line', ascending=False) 48 | print(df_city) 49 | create_map(df_city) 50 | create_line(df_city) 51 | 52 | # 哪个城市哪条线路地铁站最多 53 | print(df_line.sort_values(by='station', ascending=False)) 54 | 55 | # 去除重复换乘站的地铁数据 56 | df_station = df.groupby(['city', 'station']).count().reset_index() 57 | print(df_station) 58 | 59 | # 统计每个城市包含地铁站数(已去除重复换乘站) 60 | print(df_station.groupby(['city']).count().reset_index().sort_values(by='station', ascending=False)) 61 | 62 | 63 | def create_wordcloud(df): 64 | """ 65 | 生成地铁名词云 66 | """ 67 | # 分词 68 | text = '' 69 | for line in df['station']: 70 | text += ' '.join(jieba.cut(line, cut_all=False)) 71 | text += ' ' 72 | backgroud_Image = plt.imread('tree2.jpg') 73 | wc = WordCloud( 74 | background_color='white', 75 | mask=backgroud_Image, 76 | font_path='STXINGKA.TTF', 77 | max_words=1000, 78 | max_font_size=150, 79 | min_font_size=15, 80 | prefer_horizontal=1, 81 | random_state=50, 82 | ) 83 | wc.generate_from_text(text) 84 | img_colors = ImageColorGenerator(backgroud_Image) 85 | wc.recolor(color_func=img_colors) 86 | # 看看词频高的有哪些 87 | process_word = WordCloud.process_text(wc, text) 88 | sort = sorted(process_word.items(), key=lambda e: e[1], reverse=True) 89 | print(sort[:50]) 90 | plt.imshow(wc) 91 | plt.axis('off') 92 | wc.to_file("地铁名词云.jpg") 93 | print('生成词云成功!') 94 | 95 | 96 | create_wordcloud(df_station) 97 | 98 | words = [] 99 | for line in df['station']: 100 | for i in line: 101 | # 将字符串输出一个个中文 102 | words.append(i) 103 | 104 | 105 | def all_np(arr): 106 | """ 107 | 统计单字频率 108 | """ 109 | arr = np.array(arr) 110 | key = np.unique(arr) 111 | result = {} 112 | for k in key: 113 | mask = (arr == k) 114 | arr_new = arr[mask] 115 | v = arr_new.size 116 | result[k] = v 117 | return result 118 | 119 | 120 | def create_word(word_message): 121 | """ 122 | 生成柱状图 123 | """ 124 | attr = [j[0] for j in word_message] 125 | v1 = [j[1] for j in word_message] 126 | bar = Bar("中国地铁站最爱用的字", title_pos='center', title_top='18', width=800, height=400) 127 | bar.add("", attr, v1, is_stack=True, is_label_show=True) 128 | bar.render("中国地铁站最爱用的字.html") 129 | 130 | 131 | word = all_np(words) 132 | word_message = sorted(word.items(), key=lambda x: x[1], reverse=True)[:10] 133 | create_word(word_message) 134 | 135 | # 选取上海的地铁站 136 | df1 = df_station[df_station['city'] == '上海'] 137 | print(df1) 138 | # 选取上海地铁站名字包含路的数据 139 | df2 = df1[df1['station'].str.contains('路')] 140 | print(df2) 141 | 142 | # 选取武汉的地铁站 143 | df1 = df_station[df_station['city'] == '武汉'] 144 | print(df1) 145 | # 选取武汉地铁站名字包含家的数据 146 | df2 = df1[df1['station'].str.contains('家')] 147 | print(df2) 148 | 149 | # 选取重庆的地铁站 150 | df1 = df_station[df_station['city'] == '重庆'] 151 | print(df1) 152 | # 选取重庆地铁站名字包含家的数据 153 | df2 = df1[df1['station'].str.contains('家')] 154 | print(df2) 155 | 156 | # 选取哈尔滨的地铁站 157 | df1 = df_station[df_station['city'] == '哈尔滨'] 158 | print(df1) 159 | # 选取哈尔滨地铁站名字包含家的数据 160 | df2 = df1[df1['station'].str.contains('路')] 161 | print(df2) 162 | # 选取哈尔滨的地铁站 163 | df1 = df_station[df_station['city'] == '哈尔滨'] 164 | print(df1) 165 | # 选取哈尔滨地铁站名字包含家的数据 166 | df2 = df1[df1['station'].str.contains('街')] 167 | print(df2) 168 | 169 | 170 | def create_door(door): 171 | """ 172 | 生成柱状图 173 | """ 174 | attr = [j for j in door['city'][:3]] 175 | v1 = [j for j in door['line'][:3]] 176 | bar = Bar("地铁站最爱用“门”命名的城市", title_pos='center', title_top='18', width=800, height=400) 177 | bar.add("", attr, v1, is_stack=True, is_label_show=True, yaxis_max=40) 178 | bar.render("地铁站最爱用门命名的城市.html") 179 | 180 | 181 | # 选取地铁站名字包含门的数据 182 | df1 = df_station[df_station['station'].str.contains('门')] 183 | # 对数据进行分组计数 184 | df2 = df1.groupby(['city']).count().reset_index().sort_values(by='line', ascending=False) 185 | print(df2) 186 | create_door(df2) 187 | 188 | 189 | # 选取北京的地铁站 190 | df1 = df_station[df_station['city'] == '北京'] 191 | print(df1) 192 | # 选取北京地铁站名字包含门的数据 193 | df2 = df1[df1['station'].str.contains('门')] 194 | print(df2) 195 | 196 | # 选取南京的地铁站 197 | df1 = df_station[df_station['city'] == '南京'] 198 | # 选取南京地铁站名字包含门的数据 199 | df2 = df1[df1['station'].str.contains('门')] 200 | print(df2) 201 | 202 | # 选取西安的地铁站 203 | df1 = df_station[df_station['city'] == '西安'] 204 | # 选取西安地铁站名字包含门的数据 205 | df2 = df1[df1['station'].str.contains('门')] 206 | print(df2) 207 | 208 | #选取数量前5个名字中带有大学的地铁站的城市,并绘制柱状图 209 | df1=df[df['station'].str.contains('大学')] 210 | city_counts=df1['city'].value_counts() 211 | plt.figure(figsize=(10,5)) 212 | labelline=list(city_counts[:5].index)# 213 | print(labelline)#['上海', '沈阳', '北京', '天津', '重庆'] 214 | plt.xlabel('城市') 215 | plt.ylabel('站点数量') 216 | plt.title('名字中带有大学的地铁站的城市数量分布') 217 | plt.bar([i for i in labelline],city_counts[:5]) 218 | 219 | # 汉字字体,优先使用楷体,找不到则使用黑体 220 | plt.rcParams['font.sans-serif'] = ['Kaitt', 'SimHei'] 221 | # 正常显示负号 222 | plt.rcParams['axes.unicode_minus'] = False 223 | 224 | plt.savefig('./名字中带有大学的地铁站的城市数量分布') 225 | 226 | 227 | #绘制北京、武汉、天津、上海等各线路站点数量的折线图趋势分布 228 | #北京: 229 | df1=df[df['city']=='北京'] 230 | Bei_station=df1['line'].value_counts() 231 | print(Bei_station) 232 | plt.figure(figsize=(12,6)) 233 | labelline=list(Bei_station[:8].index) 234 | plt.xlabel=('线路') 235 | plt.ylabel=('各站点数量') 236 | plt.title("北京各线路站点数量的分布趋势") 237 | plt.plot([i for i in labelline],Bei_station[:8]) 238 | plt.savefig('./北京各线路站点数量的分布趋势') 239 | #plt.show() 240 | 241 | 242 | #武汉 243 | df1=df[df['city']=='武汉'] 244 | Wu_station=df1['line'].value_counts() 245 | print(Wu_station) 246 | plt.figure(figsize=(12,6)) 247 | labelline=list(Wu_station[:8].index) 248 | plt.xlabel=('线路') 249 | plt.ylabel=('各站点数量') 250 | plt.title("武汉各线路站点数量的分布趋势") 251 | plt.plot([i for i in labelline],Wu_station[:8]) 252 | plt.savefig('./武汉各线路站点数量的分布趋势') 253 | # plt.show() 254 | 255 | #天津 256 | df1=df[df['city']=='天津'] 257 | Tian_station=df1['line'].value_counts() 258 | print(Tian_station) 259 | plt.figure(figsize=(12,6)) 260 | labelline=list(Tian_station[:8].index) 261 | plt.xlabel=('线路') 262 | plt.ylabel=('各站点数量') 263 | plt.title("天津各线路站点数量的分布趋势") 264 | plt.plot([i for i in labelline],Tian_station[:8]) 265 | plt.savefig('./天津各线路站点数量的分布趋势') 266 | # plt.show() 267 | 268 | #上海 269 | df1=df[df['city']=='上海'] 270 | Shang_station=df1['line'].value_counts() 271 | print(Shang_station) 272 | plt.figure(figsize=(12,6)) 273 | labelline=list(Shang_station[:8].index) 274 | plt.xlabel=('线路') 275 | plt.ylabel=('各站点数量') 276 | plt.title("上海各线路站点数量的分布趋势") 277 | plt.plot([i for i in labelline],Shang_station[:8]) 278 | plt.savefig('./上海各线路站点数量的分布趋势') 279 | # plt.show() 280 | 281 | #哈尔滨 282 | df1=df[df['city']=='哈尔滨'] 283 | Ha_station=df1['line'].value_counts() 284 | print(Ha_station) 285 | plt.figure(figsize=(12,6)) 286 | labelline=list(Ha_station[:8].index) 287 | plt.xlabel=('线路') 288 | plt.ylabel=('各站点数量') 289 | plt.title("哈尔滨各线路站点数量的分布趋势") 290 | plt.plot([i for i in labelline],Ha_station[:8]) 291 | plt.savefig('./哈尔滨各线路站点数量的分布趋势') 292 | # plt.show() 293 | 294 | 295 | #各个城市的线路数量的饼状图分布 296 | line_count=df['city'].value_counts() 297 | plt.figure(figsize=(10,7)) 298 | plt.pie(line_count,labels=line_count.index,autopct='%1.1f%%') 299 | plt.title('各个城市的线路数量的饼状图分布') 300 | plt.savefig('./各个城市的线路数量的饼状图分布') 301 | # plt.show() 302 | 303 | #各个城市的站点数量的饼状图分布 304 | #饼状图展示 305 | df_station = df.groupby(['city', 'station']).count().reset_index() #此处去除每个城市的重复换乘站点数,得到实际数量的站点数量 306 | df1=df_station.groupby(['city']).count().reset_index().sort_values(by='station', ascending=False) 307 | df1['city']=df1['city']+'(站点数'+df1['station'].map(str)+')' 308 | line_count=df1['station'] 309 | plt.figure(figsize=(10,7)) 310 | plt.pie(line_count,labels=df1['city'],autopct='%1.1f%%') 311 | plt.title('各个城市的站点数量的饼状图分布') 312 | plt.savefig('./各个城市的站点数量的饼状图分布') 313 | #plt.show() 314 | 315 | #散点图展示 316 | df_station = df.groupby(['city', 'station']).count().reset_index() #此处去除每个城市的重复换乘站点数,得到实际数量的站点数量 317 | df1=df_station.groupby(['city']).count().reset_index().sort_values(by='station', ascending=False) 318 | line_count=df1['station'] 319 | plt.figure(figsize=(10,7)) 320 | plt.xlabel=('城市') 321 | plt.ylabel=('站点数量') 322 | plt.scatter(x=df1['city'],y=line_count,marker='*') 323 | plt.title('各个城市的站点数量的散点图分布') 324 | plt.savefig('./各个城市的站点数量的散点图分布') 325 | #plt.show() 326 | 327 | #各城市的每条线路的站点数量的变化 折线图 328 | df1=df_line.sort_values(by='station', ascending=False)#by中指定按照什么列排序,ascending中默认升序排列,值为True 329 | station_count=df1['line']+df1['city'] 330 | plt.figure(figsize=(15,8)) 331 | labelline=list(station_count[:12]) 332 | plt.xlabel=('线路') 333 | plt.ylabel=('各站点数量') 334 | plt.title("各城市各线路的站点数量前10的变化") 335 | plt.plot([i for i in labelline],df1['station'][:12]) 336 | plt.savefig('./各城市各线路的站点数量前10的变化') 337 | #plt.show() 338 | 339 | #每个城市的哪条线路的地铁站点数量最多 柱形图 340 | df_1=df_line.sort_values(by='station', ascending=False) 341 | df_2=df_1.groupby('city')['station'].max().reset_index(drop=False)#保留索引 342 | line_station_c=df_2.sort_values(by='station',ascending=False) 343 | # line_station_c.to_csv("../1.csv",header=False,index=False) 344 | plt.figure(figsize=(15,5)) 345 | labelline=list(line_station_c['city']) 346 | # line_text=pd.merge(left=line_station_c,right=df_1,on=['city','station'],how='inner') 347 | # line_text.to_csv("../2.csv",header=False,index=False) 348 | labelline=labelline#+line_text['line'].map(str) 349 | plt.xlabel=('城市') 350 | plt.ylabel=('站点数量') 351 | plt.bar([i for i in labelline],line_station_c['station']) 352 | plt.title('每个城市哪条线路的站点数最多') 353 | plt.savefig('./每个城市哪条线路的站点数最多') 354 | #plt.show() 355 | 356 | #统计各个城市的大学数量,然后利用回归图进行拟合(分析各个城市的大学数量与站点数量的关系 357 | df_uni= pd.read_csv('./university.csv', header=None, names=['city', 'uni_count'], encoding='gbk') 358 | df_uni=pd.merge(left=line_station_c,right=df_uni,on='city',how='inner') #将两个表格中的数据基于city列进行内连接。 359 | x=df_uni['uni_count'] 360 | y=df_uni['station'] 361 | sns.regplot(x=x,y=y,color='b') 362 | plt.title('分析各个城市的大学数量与站点数量的关系') 363 | plt.savefig('./分析各个城市的大学数量与站点数量的关系') 364 | #plt.show() 365 | 366 | #散点图 367 | fig=plt.figure(figsize=(10,7)) 368 | plt.xlabel=('站点数量') 369 | plt.ylabel=('大学数量') 370 | plt.title('各个城市的大学数量与站点数量的关系') 371 | plt.scatter(x=x,y=y,cmap='b',marker='*',alpha=0.8) 372 | plt.grid() 373 | plt.savefig('./各个城市的大学数量与站点数量的关系') #plt.show() 374 | 375 | #seaborn的双变量图:可以查看多变量之间的分布关系,也可以显示它本身的单变量情况 376 | 377 | df_s=df_uni 378 | sns.jointplot(x='uni_count',y='station',data=df_s) 379 | plt.savefig('./大学数量与站点数量的双变量图') 380 | #plt.show() 381 | plt.close() 382 | 383 | #选取郑州、武汉、广州、长沙同名的线路1-线路6,绘制折线图分析这些城市的目标线路的站点数量分布 384 | df_1=df_line.sort_values(by='station', ascending=False) 385 | zz_=df_1[df_1['city']=='郑州'].sort_values(by='line',ascending=False).reset_index()#ascending参数值为False时,则数据按指定列降序排序。 386 | zz_=zz_.loc[zz_['line'].isin(['1号线','2号线','3号线','4号线','5号线','6号线'])] 387 | 388 | wh_=df_1[df_1['city']=='武汉'].sort_values(by='line',ascending=False).reset_index() 389 | wh_=wh_.loc[wh_['line'].isin(['1号线','2号线','3号线','4号线','5号线','6号线'])] 390 | 391 | gz_=df_1[df_1['city']=='广州'].sort_values(by='line',ascending=False).reset_index() 392 | gz_=gz_.loc[gz_['line'].isin(['1号线','2号线','3号线','4号线','5号线','6号线'])] 393 | 394 | cs_=df_1[df_1['city']=='长沙'].sort_values(by='line',ascending=False).reset_index() 395 | cs_=cs_.loc[cs_['line'].isin(['1号线','2号线','3号线','4号线','5号线','6号线'])] 396 | 397 | print(zz_) 398 | print(wh_) 399 | print(gz_) 400 | print(cs_) 401 | plt.figure(figsize=(10,7)) 402 | L1=plt.plot(zz_['line'],zz_['station'],color='b',label='郑州线路1-6的站点数量变化') 403 | L2=plt.plot(wh_['line'],wh_['station'],color='g',label='武汉线路1-6的站点数量变化') 404 | L3=plt.plot(gz_['line'],gz_['station'],color='r',label='广州线路1-6的站点数量变化') 405 | L4=plt.plot(cs_['line'],cs_['station'],color='k',label='长沙线路1-6的站点数量变化') 406 | plt.legend() 407 | plt.title('郑州、武汉、广州、长沙同名的线路1-线路6的站点数量分布') 408 | plt.xlabel=('线路1-线路6') 409 | plt.ylabel=('站点数量') 410 | plt.savefig('./郑州、武汉、广州、长沙同名的线路1-线路6的站点数量分布') 411 | #plt.show() 412 | 413 | #选取广州、天津、武汉、重庆同名的线路1-线路6,绘制折线图分析这些城市的目标线路的站点数量分布 414 | df_1=df_line.sort_values(by='station', ascending=False) 415 | zz_=df_1[df_1['city']=='广州'].sort_values(by='line',ascending=False).reset_index()#ascending参数值为False时,则数据按指定列降序排序。 416 | zz_=zz_.loc[zz_['line'].isin(['1号线','2号线','3号线','4号线','5号线','6号线'])] 417 | 418 | wh_=df_1[df_1['city']=='天津'].sort_values(by='line',ascending=False).reset_index() 419 | wh_=wh_.loc[wh_['line'].isin(['1号线','2号线','3号线','4号线','5号线','6号线'])] 420 | 421 | gz_=df_1[df_1['city']=='武汉'].sort_values(by='line',ascending=False).reset_index() 422 | gz_=gz_.loc[gz_['line'].isin(['1号线','2号线','3号线','4号线','5号线','6号线'])] 423 | 424 | cs_=df_1[df_1['city']=='重庆'].sort_values(by='line',ascending=False).reset_index() 425 | cs_=cs_.loc[cs_['line'].isin(['1号线','2号线','3号线','4号线','5号线','6号线'])] 426 | 427 | print(zz_) 428 | print(wh_) 429 | print(gz_) 430 | print(cs_) 431 | plt.figure(figsize=(10,7)) 432 | L1=plt.plot(zz_['line'],zz_['station'],color='b',label='广州线路1-6的站点数量变化') 433 | L2=plt.plot(wh_['line'],wh_['station'],color='g',label='天津线路1-6的站点数量变化') 434 | L3=plt.plot(gz_['line'],gz_['station'],color='r',label='武汉线路1-6的站点数量变化') 435 | L4=plt.plot(cs_['line'],cs_['station'],color='k',label='重庆线路1-6的站点数量变化') 436 | plt.legend() 437 | plt.title('广州、天津、武汉、重庆同名的线路1-线路6的站点数量分布') 438 | plt.xlabel=('线路1-线路6') 439 | plt.ylabel=('站点数量') 440 | plt.savefig('./广州、天津、武汉、重庆同名的线路1-线路6的站点数量分布') 441 | #plt.show() 442 | 443 | #全国各城市的总的换乘站点数量(2换乘、3换乘、4换乘等)分布统计 444 | df_1=df.groupby(['city','station']).count().reset_index() 445 | print(df_1) 446 | df_1=df_1[df_1['line']>1]#筛选出来全国的换乘站点数 447 | tran_sit=df_1.groupby('line').count().reset_index() #保留原索引,但是值是count()函数计数之后的值 448 | plt.figure(figsize=(10,5)) 449 | plt.xlabel=('站点可换乘等级') 450 | plt.ylabel=('站点数量') 451 | plt.bar(tran_sit['line'],tran_sit['station'],color='g') 452 | plt.title('全国各城市总的换乘站点数量(2换乘、3换乘、4换乘等)分布统计') 453 | plt.savefig('./全国各城市总的换乘站点数量(2换乘、3换乘、4换乘等)分布统计') 454 | #plt.show() 455 | print(tran_sit[tran_sit['line']==5]['station']) 456 | 457 | 458 | -------------------------------------------------------------------------------- /src/Search.py: -------------------------------------------------------------------------------- 1 | import sqlite3 2 | import tkinter as tk 3 | from tkinter import scrolledtext 4 | 5 | # 存储查询到的结果 6 | infomation = [] 7 | 8 | # 查询地铁线路 9 | def search_line(sstr): 10 | global infomation 11 | result = sstr.split(",") 12 | print(result) 13 | 14 | sql = "select city,line,name from info where city="+ "'" + result[0] +"'" + " and " + "line=" +"'" + result[1] +"'" 15 | print(sql) 16 | s = conn.cursor().execute(sql) 17 | for i in s: 18 | infomation.append(str(i[0])+' '+str(i[1])+' '+str(i[2])) 19 | 20 | scr = scrolledtext.ScrolledText(root, width=62, height=43) 21 | scr.place(x=75, y=200) 22 | 23 | n = len(infomation) 24 | print(n) 25 | ss = '' 26 | for i in range(n): 27 | print(infomation[i]) 28 | ss = ss + infomation[i] + '\n' 29 | scr.insert('end',ss) 30 | infomation = [] 31 | src.pack() 32 | 33 | # 查询站点 34 | def search_station(sstr): 35 | global infomation 36 | sql = "select city,line,name from info where name="+ "'" + sstr +"'" 37 | print(sql) 38 | s = conn.cursor().execute(sql) 39 | for i in s: 40 | infomation.append(str(i[0])+' '+str(i[1])+' '+str(i[2])) 41 | 42 | scr = scrolledtext.ScrolledText(root, width=62, height=43) #滚动文本框(宽,高(以行数为单位)) 43 | scr.place(x=75, y=200) #滚动文本框在页面的位置 44 | 45 | n = len(infomation) 46 | print(n) 47 | ss = '' 48 | for i in range(n): 49 | print(infomation[i]) 50 | ss = ss + infomation[i] + '\n' 51 | scr.insert('end',ss) 52 | infomation = [] 53 | src.pack() 54 | 55 | 56 | if __name__ == '__main__': 57 | conn = sqlite3.connect('city_line11.db', check_same_thread=False) 58 | cur = conn.cursor() 59 | HEIGHT = 800 60 | WIDTH = 600 61 | 62 | root = tk.Tk() 63 | root.title("2004010618彭伟楠") 64 | #root.geometry("600x900") 65 | canvas = tk.Canvas(root, height=HEIGHT, width=WIDTH) 66 | canvas.pack() 67 | background_image = tk.PhotoImage(file='./bg1.png') 68 | background_label = tk.Label(root, image=background_image) 69 | background_label.place(relwidth=1, relheight=1) 70 | 71 | search_text = tk.StringVar() 72 | search_text1 = tk.StringVar() 73 | 74 | lower_frame = tk.Frame(root, bg='#80c1ff',bd=10) 75 | lower_frame.place(relx=0.5, rely=0.25, relwidth=0.75, relheight=0.7,anchor='n') 76 | 77 | frame = tk.Frame(root, bg='#80c1ff', bd=5) 78 | frame.place(relx=0.5, rely=0.1, relwidth=0.75, relheight=0.1, anchor='n') 79 | 80 | entry = tk.Entry(frame, font=40,textvariable=search_text) 81 | entry.place(relwidth=0.65, relheight=1) 82 | 83 | button = tk.Button(frame, text="查线路", font=40, command=lambda: search_line(search_text.get())) 84 | button.place(relx=0.7, relheight=1, relwidth=0.3) 85 | 86 | entry1 = tk.Entry(root, font=40,bg='#80c1ff',textvariable=search_text1) 87 | entry1.place(x=82, y=5,width=280,height=60) 88 | 89 | button1 = tk.Button(text="查站点", font=40,bg='#80c1ff', command=lambda: search_station(search_text1.get())) 90 | button1.place(x=390, y=5,width=135,height=60) 91 | 92 | root.mainloop() 93 | 94 | 95 | -------------------------------------------------------------------------------- /src/Spider.py: -------------------------------------------------------------------------------- 1 | import json 2 | import requests 3 | import sqlite3 4 | from bs4 import BeautifulSoup 5 | import threading 6 | 7 | 8 | headers = {'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'} 9 | 10 | # 连接数据库 11 | conn = sqlite3.connect('../city_line_new.db', check_same_thread=False) 12 | cur = conn.cursor() 13 | #cur.execute('drop table info') 14 | cur.execute('create table info(city text,line text,name text)') 15 | conn.commit() 16 | # 关闭数据库 17 | #conn.close() 18 | 19 | lock = threading.Lock() 20 | lock2 = threading.Lock() 21 | 22 | def get_message(ID, cityname, name): 23 | ''' 24 | 地铁线路信息获取 25 | ''' 26 | url = 'http://map.amap.com/service/subway?_1555502190153&srhdata=' + ID + '_drw_' + cityname + '.json' 27 | response = requests.get(url=url, headers=headers) 28 | html = response.text 29 | result = json.loads(html) 30 | for i in result['l']: 31 | for j in i['st']: 32 | # 判断是否含有地铁分线 33 | if len(i['la']) > 0: 34 | print(name, i['ln'] + '(' + i['la'] + ')', j['n']) 35 | try: 36 | lock2.acquire(True) 37 | except: 38 | pass 39 | cur.execute("insert into info(city, line, name) values(?, ?, ?)", (name, i['ln'] + '(' + i['la'] + ')', j['n'])) 40 | try: 41 | lock2.release() 42 | except: 43 | pass 44 | #cur.execute('select * from info') 45 | #print(cur.fetchall()) 46 | conn.commit() 47 | with open('../subway_new.csv', 'a+', encoding='gbk') as f: 48 | f.write(name + ',' + i['ln'] + '(' + i['la'] + ')' + ',' + j['n'] + '\n') 49 | else: 50 | print(name, i['ln'], j['n']) 51 | try: 52 | lock2.acquire(True) 53 | except: 54 | pass 55 | cur.execute("insert into info(city, line, name) values(?, ?, ?)", (name, i['ln'], j['n'])) 56 | try: 57 | lock2.release() 58 | except: 59 | pass 60 | # cur.execute('select * from info') 61 | #print(cur.fetchall()) 62 | #conn.commit() 63 | with open('../subway_new.csv', 'a+', encoding='gbk') as f: 64 | f.write(name + ',' + i['ln'] + ',' + j['n'] + '\n') 65 | 66 | def get_city(): 67 | ''' 68 | 城市信息获取 69 | ''' 70 | url = 'http://map.amap.com/subway/index.html?&1100' 71 | response = requests.get(url=url, headers=headers) 72 | html = response.text 73 | # 编码 74 | html = html.encode('ISO-8859-1') 75 | html = html.decode('utf-8') 76 | soup = BeautifulSoup(html, 'lxml') 77 | # 城市列表 78 | res1 = soup.find_all(class_="city-list fl")[0] 79 | res2 = soup.find_all(class_="more-city-list")[0] 80 | return res1, res2 81 | 82 | 83 | if __name__ == '__main__': 84 | res1, res2 = get_city() 85 | 86 | for i in res1.find_all('a'): 87 | # 城市ID值 88 | ID = i['id'] 89 | # 城市拼音名 90 | cityname = i['cityname'] 91 | # 城市名 92 | name = i.get_text() 93 | # get_message(ID, cityname, name) 94 | t = threading.Thread(target=get_message, args=(ID, cityname, name,)) 95 | t.start() 96 | for i in res2.find_all('a'): 97 | # 城市ID值 98 | ID = i['id'] 99 | # 城市拼音名 100 | cityname = i['cityname'] 101 | # 城市名 102 | name = i.get_text() 103 | # get_message(ID, cityname, name) 104 | t = threading.Thread(target=get_message, args=(ID, cityname, name,)) 105 | t.start() 106 | 107 | 108 | -------------------------------------------------------------------------------- /src/bg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/src/bg1.png -------------------------------------------------------------------------------- /src/tree2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/src/tree2.jpg -------------------------------------------------------------------------------- /src/university.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkq123l/Subway_Info_Analysis_Python/3376953b254f2229b8766d56666ed8380f1859f1/src/university.csv --------------------------------------------------------------------------------