Python 绘制北上广深的地铁路线动态图

yizhihongxing

下面是详细讲解“Python 绘制北上广深的地铁路线动态图”的完整攻略。

1.准备工作

1.1 安装相关库

首先,我们需要安装几个相关的库,包括 matplotlibPillowrequests,以及xlrdopenpyxl。可以使用以下命令来进行安装:

pip install matplotlib pillow requests xlrd openpyxl

1.2 获取地铁数据

在绘制地铁路线动态图之前,我们需要获得相应的地铁数据。可以通过各种渠道获得,例如从国家或城市统计局、地铁官网或其他公开数据平台获取。此处我们以北京地铁为例,我们可以在 https://www.bjsubway.com/station/zjgls/# 获取到相应的数据。我们选择把数据保存在Excel中。

2.绘制地铁路线图

2.1 获取站点信息

首先,我们需要获取各个地铁站点的信息,包括站名、线路名、经纬度等。我们可以将这些信息保存在Excel文件中,方便后续使用。可以使用以下代码获取站点信息并保存到Excel文件中:

import requests
import xlrd
import xlwt
from xlutils.copy import copy
import time

# 获取地铁线路信息
def get_lines_info():
    url = 'https://www.bjsubway.com/station/zjgls/#'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
    response = requests.get(url, headers=headers)
    response.encoding = 'gbk'

2.2 绘制地铁路线图

在获取站点信息之后,我们可以开始绘制地铁路线图。首先,我们需要将每一条地铁线路的站点连起来,形成一条曲线。这可以使用matplotlib库中的plot函数来实现。具体来说,我们可以定义一个绘制地铁线路的函数,使用plot函数绘制站点之间的曲线。

import matplotlib.pyplot as plt

def draw_subway_lines(subway_data, filename):
    fig, ax = plt.subplots(figsize=(8, 8))
    ax.set_aspect('equal')
    ax.set_xticks([])
    ax.set_yticks([])

    lines = list(subway_data.keys())

    for line in lines:
        # 逐条线路绘制
        stations = subway_data[line]['stations']

        x_list = []
        y_list = []

        for i in range(len(stations)):
            station = stations[i]
            station_name = station[0]

            if station_name not in stations_locations:
                continue

            location = stations_locations[station_name]
            x_list.append(location['longitude'])
            y_list.append(location['latitude'])

            ax.annotate(station_name, (location['longitude'], location['latitude']))   # 显示车站名称

        ax.plot(x_list, y_list, color=subway_data[line]['color'], alpha=0.8)

    plt.savefig(filename, dpi=300)
    plt.show()

2.3 获取车站坐标信息

在将车站连线绘制出来之后,我们需要将车站的名称和经纬度对应起来,方便后续使用。我们可以从爬虫中获得车站的坐标,同时可以手动添加其他缺失的站点信息。具体来说,我们可以从Excel文件中读取车站信息,将车站名称和坐标存储到字典stations_locations中。

# 加载车站信息
def load_stations_info(filename):
    stations_locations = {}

    with xlrd.open_workbook(filename) as workbook:
        for sheetname in workbook.sheet_names():
            sheet = workbook.sheet_by_name(sheetname)

            for row in range(1, sheet.nrows):  
                station_name = sheet.cell_value(row, 0)  
                longitude = float(sheet.cell_value(row, 2))  
                latitude = float(sheet.cell_value(row, 3))  

                stations_locations[station_name] = {'longitude': longitude, 'latitude': latitude}

    return stations_locations

3.绘制动态图

最后,我们可以将多张静态图片合成一张动态图,以便更好地展现地铁线路的变化。我们可以使用Pillow库中的ImageSequence类进行动态图的处理。具体来说,我们可以定义一个生成地铁路线动态图的函数generate_gif,使用ImageSequence类读取并合并多张静态图片,生成一张包含所有图片的动态图。

import os
from PIL import Image, ImageSequence

def generate_gif(image_files, output_gif):
    images = []
    for filename in image_files:
        images.append(Image.open(filename))

    images[0].save(output_gif, save_all=True, append_images=images[1:], optimize=False, duration=500, loop=0)

接下来是一个完整的示例,生成北京地铁路线的动态图:

import requests
import xlrd
import xlwt
from xlutils.copy import copy
import time
import matplotlib.pyplot as plt
from PIL import Image, ImageSequence

def get_lines_info():
    url = 'https://www.bjsubway.com/station/zjgls/#'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
    response = requests.get(url, headers=headers)
    response.encoding = 'gbk'

    # 获取地铁线路信息
    subway_data = {}
    tags = response.text.split('<a class="title"')
    for tag in tags:
        if tag.find('线</a>') == -1:
            continue

        color_pos = tag.find('background-color:')
        if color_pos == -1:
            continue
        color_start = color_pos + len('background-color:#')
        color_end = tag.find(';"><', color_start)
        color = '#' + tag[color_start:color_end]
        line_info = tag.split('class="station">')

        stations = []
        for station_info in line_info:
            if station_info.find('站</a>') == -1:
                continue

            station_start = station_info.find('">') + len('">')
            station_end = station_info.find('</a>', station_start)
            station_name = station_info[station_start:station_end]
            stations.append((station_name, color))

        line_name = line_info[0].split('">')[1].split('线')[0]
        subway_data[line_name] = {'color': color, 'stations': stations}

    return subway_data

def draw_subway_lines(subway_data, stations_locations, filename):
    fig, ax = plt.subplots(figsize=(8, 8))
    ax.set_aspect('equal')
    ax.set_xticks([])
    ax.set_yticks([])

    lines = list(subway_data.keys())

    for line in lines:
        # 逐条线路绘制
        stations = subway_data[line]['stations']

        x_list = []
        y_list = []

        for i in range(len(stations)):
            station = stations[i]
            station_name = station[0]

            if station_name not in stations_locations:
                continue

            location = stations_locations[station_name]
            x_list.append(location['longitude'])
            y_list.append(location['latitude'])

            ax.annotate(station_name, (location['longitude'], location['latitude']))   # 显示车站名称

        ax.plot(x_list, y_list, color=subway_data[line]['color'], alpha=0.8)

    plt.savefig(filename, dpi=300)
    plt.show()

def load_stations_info(filename):
    stations_locations = {}

    with xlrd.open_workbook(filename) as workbook:
        for sheetname in workbook.sheet_names():
            sheet = workbook.sheet_by_name(sheetname)

            for row in range(1, sheet.nrows):  
                station_name = sheet.cell_value(row, 0)  
                longitude = float(sheet.cell_value(row, 2))  
                latitude = float(sheet.cell_value(row, 3))  

                stations_locations[station_name] = {'longitude': longitude, 'latitude': latitude}

    return stations_locations

def generate_gif(image_files, output_gif):
    images = []
    for filename in image_files:
        images.append(Image.open(filename))

    images[0].save(output_gif, save_all=True, append_images=images[1:], optimize=False, duration=500, loop=0)

if __name__ == '__main__':
    # 1.准备工作

    ## 1.1 安装相关库
    # pip install matplotlib pillow requests xlrd openpyxl

    ## 1.2 获取地铁数据
    subway_data = get_lines_info()

    # 2.绘制地铁路线图

    ## 2.1 获取站点信息
    filename = 'stations.xlsx'
    stations_locations = load_stations_info(filename)

    ## 2.2 绘制地铁路线图
    image_files = []
    for line in subway_data:
        filename = f"{line}.png"
        draw_subway_lines({line: subway_data[line]}, stations_locations, filename)
        image_files.append(filename)

    ## 2.3 获取车站坐标信息

    # 3.绘制动态图
    output_gif = 'subway.gif'
    generate_gif(image_files, output_gif)

以上是一个完整的示例,生成北京地铁路线的动态图。类似的方法也可以用于绘制其他城市的地铁路线图。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python 绘制北上广深的地铁路线动态图 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • Python 列表的基本操作介绍

    以下是详细讲解“Python列表的基本操作介绍”的完整攻略。 在Python中,列表是一种非常常用的数据类型,它可以存储多个元素,并且支持各种操作。本文将介绍Python列表的基本操作,包括创建列表、访问列表元素、添加和删除元素、列表切片、列表排序等。 创建列表 在Python中,可以使用方括号[]或list()函数来创建一个列表。例如: lst1 = [1…

    python 2023年5月13日
    00
  • python 爬虫如何正确的使用cookie

    Python爬虫如何正确使用cookie的完整攻略 什么是cookie Cookie,指的是网站为了辨别用户身份,维护登录态,而储存在用户本地终端上的数据。通俗的来讲,当我们在浏览器里面登录某个网站时,这个网站会向我们浏览器中写入一些数据,这就是cookie。 爬虫模拟登录网站时需要注意的是,要在请求头中加入cookie,模拟用户已经通过登录验证的状态。否则…

    python 2023年5月14日
    00
  • Python 的 with 语句详解

    Python 的 with 语句详解 在Python中,我们常常需要打开文件、连接数据库等等需要进行资源管理的操作。这些操作需要我们在使用之后手动关闭,否则会造成一些异常情况的发生。Python的with语句就是专门为这种场景而设计的。 with 语句的语法 with语句可以方便地管理文件、网络连接等资源对象。其语法如下所示: with `expressio…

    python 2023年6月5日
    00
  • python解析yaml文件过程详解

    YAML是一种轻量级的数据序列化格式,常用于配置文件和数据交换。Python提供了多种解析YAML文件的方法,包括PyYAML和ruamel.yaml等。以下是详细讲解Python解析YAML文件过程的攻略,包含两个示例。 示例1:使用PyYAML解析YAML文件 以下是一个示例,可以使用PyYAML解析YAML文件: import yaml # 读取YAM…

    python 2023年5月15日
    00
  • Python使用urllib模块的urlopen超时问题解决方法

    什么是urlopen超时问题 在使用Python中的urllib模块的urlopen方法打开URL链接时,如果服务器响应时间超过默认的超时时间,那么该方法将会一直阻塞等待直到服务器响应完成,这就是urlopen的超时问题。 urlopen超时问题的解决方法 为了解决这个问题,可以使用以下两种方法: 2.1. 设置超时时间参数 在调用urlopen方法时,可以…

    python 2023年6月3日
    00
  • Python json格式化打印实现过程解析

    当我们在处理 Python 中的 JSON 数据时,有时需要对 JSON 数据进行格式化打印输出。Python 中的 json 模块可以实现对 JSON 数据的格式化处理,下面我们将详细讲解 Python json 格式化打印的实现过程。 1. 加载 JSON 数据 在 Python 中,我们需要通过 json 模块来处理 JSON 数据。使用 json.l…

    python 2023年6月3日
    00
  • 使用Python+Splinter自动刷新抢12306火车票

    以下是“使用Python+Splinter自动刷新抢12306火车票”的完整攻略。 1. Splinter简介 Splinter是一个基于Selenium WebDriver的开源自动化测试框架,它允许我们用几行Python代码来控制浏览器进行自动化测试、爬取数据等工作。 2. 环境要求 Python 3 Chrome浏览器 ChromeDriver 3. …

    python 2023年5月19日
    00
  • Python函数参数和注解的使用

    下面是Python函数参数和注解的使用攻略: 函数参数类型 位置参数 位置参数类似于命令行参数,定义函数时需要指定参数的顺序和类型。 def add(x, y): return x + y add(1, 2) # 输出3 默认参数 默认参数在定义函数时就已经确定了默认值,在函数调用时可以不传入对应的参数值。如果传参,则会覆盖默认值。 def greeting…

    python 2023年6月5日
    00
合作推广
合作推广
分享本页
返回顶部