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生成从对数正态分布中随机数需要使用到numpy和scipy库,因此需要先导入这两个库。 import numpy as np from scipy.stats import lognorm 步骤二:设定分布的参数 对数正态分布是由三个参数确定的,即均值 $\mu$、…

    python-answer 2023年3月25日
    00
  • Python3 全自动更新已安装的模块实现

    下面我将为您详细讲解Python3全自动更新已安装的模块实现的完整攻略。 方案概述 Python3提供了pip工具管理Python包,可以通过pip更新、安装、删除已安装的库。如果我们需要全自动更新已安装的Python包,需要使用以下方案: 使用pip列出已安装的库 遍历所有已安装的库,使用pip更新 涉及到的Python包及版本信息如下: Python3.…

    python 2023年5月19日
    00
  • 如何使用 Redis 的缓存功能来提高网站性能?

    以下是详细讲解如何使用 Redis 的缓存功能来提高网站性能的完整使用攻略。 Redis 缓存简介 Redis 是一种高性能的键值存储数据库,支持多种结构和高级功能。其中,缓存是 Redis 的一个重要功能,可以用于提高网站性能。Redis 缓存的特点如下: Redis 缓存是基于内存,读写速度非常快。 Redis 缓存是分布式的,可以将缓存数据分布在个节点…

    python 2023年5月12日
    00
  • python字典翻转的实现

    Python中的字典是一种集合数据类型,用{}包围,由key-value键值对组成。字典可以通过key来访问对应的value, 但是很难通过value来访问对应的key。因此,如果需要倒置字典中的key-value键值对,就需要进行字典翻转。下面是Python字典翻转的实现攻略: 方法一:使用dictionary comprehension(字典推导) 在P…

    python 2023年6月3日
    00
  • Python for Informatics 第11章 正则表达式(一)

    PythonforInformatics第11章正则表达式(一)攻略 本攻略将详细讲解PythonforInformatics第11章正则表达式(一)的内容,包括正则表达式的基本语法、常用的正则表达式模式、以及如何在Python中使用正则表达式。 正则表达式基本语法 正则表达式是一种用于匹配文本的模式。在Python中,我们可以使用re模块来使用正则表达式。…

    python 2023年5月14日
    00
  • python xlwt模块的使用解析

    下面我来详细讲解“pythonxlwt模块的使用解析”的完整实例教程。 一、 xlwt模块简介 xlwt模块是Python中一个用于管理Excel文件的模块,用以将数据以Excel表格的形式写入到Excel文件中。它具有操作方便、支持多种Excel文件格式等优点,因此,被广泛应用于数据处理、表格导出等方面。 二、 xlwt模块的安装 使用pip安装xlwt模…

    python 2023年5月13日
    00
  • Python基于进程池实现多进程过程解析

    Python基于进程池实现多进程过程解析 概述 多进程是指同时启动多个进程进行任务处理,相互之间互不干扰,可以高效利用计算机的多核心资源,从而提高任务处理的效率。使用 Python 中的 multiprocessing 模块,可以方便地实现多进程处理。其中,进程池是一种常用的多进程解决方案。 进程池的概念 进程池是由多个常驻进程组成的进程组,该进程组中的进程…

    python 2023年6月7日
    00
  • Python数字图像处理代数之加减乘运算

    Python数字图像处理代数之加减乘运算 在数字图像处理中,对图像进行代数运算可以实现许多有用的功能。Python作为一种高级编程语言,拥有丰富的科学计算和图像处理库,可以方便地进行数字图像处理代数运算。 本文将介绍Python数字图像处理代数之加减乘运算的完整攻略,包括如何完成这些运算以及代码示例。 图像加法运算 图像加法运算可以在两幅图像之间进行,将对应…

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