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

下面是详细讲解“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程序流程控制结构的完整攻略,帮助大家掌握这一重要知识点。 1. if语句 if语句是Python中最基本、也是最常用的流程控制结构之一。它可以根据条件来控制程序的执行流程。 以下是…

    python 2023年5月30日
    00
  • Python定时任务框架APScheduler安装使用详解

    Python定时任务框架APScheduler安装使用详解 一、概述 APScheduler是Python的一个开源的任务调度框架,可以用来执行定时任务、循环任务、一次性任务等。 APScheduler支持多种存储模式,并且提供了灵活的RESTful API和WebSocket接口,可以实现与其他服务进行交互。同时,APScheduler是跨平台和可扩展的,…

    python 2023年6月5日
    00
  • 如何使用scrapy中的ItemLoader提取数据

    下面是关于如何使用Scrapy中的ItemLoader提取数据的完整攻略。 1. ItemLoader简介 Scrapy中的ItemLoader是专门用于从网页中提取数据的工具,它可以根据规则从网页中提取数据,并把提取的数据存储到Scrapy的Item对象中。 ItemLoader的主要作用如下: 简化数据提取的过程,提高代码的复用性; 支持添加自定义的输入…

    python 2023年6月3日
    00
  • Python requests发送post请求的一些疑点

    以下是关于Python requests发送POST请求的一些疑点的攻略: Python requests发送POST请求的一些疑点 在使用Python requests发送POST请求时,可能会遇到一些疑点。以下是Python requests发送POST请求的一些疑点的攻略。 POST请求的请求体 在发送POST请求时,需要设置请求体。以下是设置POST…

    python 2023年5月14日
    00
  • pandas DataFrame数据转为list的方法

    Pandas DataFrame数据转为List的方法 在Python中,Pandas是一个常用的数据处理库,它提供了DataFrame数据结构来处理和分析数据。有时候我们需要将DataFrame数据转换为List类型,以便于进行其他操作。攻略将介绍Pandas DataFrame数据转List的方法,包括使用属性和to_numpy()方法。 使用value…

    python 2023年5月13日
    00
  • 详解Python PIL ImagePath.Path.getbbox()方法

    Python中的PIL模块是个非常有用的模块,提供了很多处理图像的方法和工具。在该模块中,ImagePath是其中的一个子模块,该子模块提供了一类可用于解析和操作路径的类,路径可以是 SVG 路径或者 W3C-path-data 。 ImagePath.Path.getbbox()方法是ImagePath.Path类的其中一个方法,它用于返回符合路径描边的最…

    python-answer 2023年3月25日
    00
  • 浅析python中特殊文件和特殊函数

    浅析Python中特殊文件和特殊函数 在Python中,有一些特殊的文件和函数。它们在代码执行过程中扮演着重要的角色,简化了代码实现的过程。本文将对这些特殊的文件和函数进行简要分析。 特殊文件 __init__.py 在Python中,每个文件夹都可以作为一个模块被调用,其中的__init__.py文件作为该模块的初始化文件。该文件可以包含模块所需的全局变量…

    python 2023年5月13日
    00
  • 用Python构建GUI应用的铅笔草图

    本文我们来详细讲解使用 Python 构建 GUI 应用的步骤和技术。 构建 GUI 应用的基本步骤 选择 GUI 库:Python 中可以使用多个 GUI 库,比如 Tkinter、PyQt、wxPython 等。选择适合自己的 GUI 库是第一步。 设计 GUI 界面:在选择 GUI 库之前,就需要先确定所需的界面布局和界面元素(例如,按钮、标签、文本框…

    python-answer 2023年3月25日
    00
合作推广
合作推广
分享本页
返回顶部