Python 学习之 3 —— 基于basemap绘图的路径示意图

简介

之前通过basemap画出了南京市地图,并在地图上标志几个散点的位置。

Basemap安装教程和示例程序:
https://blog.****.net/lovetaozibaby/article/details/87723939

现在需要在此地图的基础上,完成下面任务:

  1. 给出初始位置,将初始位置和这10个点的位置在途中用不同的图示显示,并画出图例
  2. 将初始位置和这10个点,按照给定的顺序连接起来,并将最后一个点与初始位置相连。也就是说,画出一个人从初始位置出发,走完这十个点,并且回到初始位置的路径。

python程序

1. 画任意两点间的连线(带方向箭头)

为了减少不必要的重复(11个点需要些11句画连接线的程序),这里定义了一个画两点之间连接线的子程序。

该程序的作用是,给出两个两个点的位置:画出从A 点到B点的连接线,并带箭头示意方向。

A:(x_begin,y_begin);
B:(x_end,y_end);

head_width 表示箭头的宽度;
head_length 表示箭头的长度;

fc 表示箭头填充的颜色;
ec 表示连接线和箭头外部的颜色;

程序如下:

def plt_arrow(x_begin,y_begin,x_end,y_end,color):

    plt.arrow(x_begin, y_begin, x_end - x_begin, y_end - y_begin,
             length_includes_head=True,     
             head_width = 500, head_length = 1000, fc=color, ec=color)

要注意的是,这里的head_width 和 head_length 取500和1000的原因是,正如简介里所说,本程序是在basemap画南京市地图的基础上处理图形的。将500和1000换算到经纬度地图中后,其实现实出来的大小是非常小的。但是如果要用在一般的绘图中,head_width 取0.25即可。当然,具体问题还需要具体分析。

参考网址:https://blog.****.net/qq_33039859/article/details/79130918

2. 路径示意图

已知出发点位置O:(x0,y0),还有接下来的十个点的路径,并且要返回始发点。

(x0,y0):始发点
(x,y) :10个点的位置

N_begin:第一要去的位置在(x,y)中的***
N_end: 最后一个要去的位置在(x,y)中的***

color :颜色设置(因为最后画的路径有好多条,这里要区分出每个不同的路径)

matplotlib 里提供了各种各样的颜色和线条,如果想查看颜色的话,可以在下面的网址中:https://www.cnblogs.com/darkknightzh/p/6117528.html

程序如下:

def route1(x0, y0, x, y, plt, N_begin, N_end,color):
    for i in range(N_begin, N_end):
        if i == N_begin:
            x_begin,y_begin = x0, y0
            x_end, y_end = x[i], y[i]

        if N_begin <i < N_end - 1:
            x_begin, y_begin = x[i], y[i]
            x_end, y_end = x[i+1], y[i+1]

        if i == N_end - 1:
            x_begin, y_begin = x[i], y[i]
            x_end, y_end = x0, y0

        plt_arrow(x_begin, y_begin, x_end, y_end, color)

3. 添加图例

添加图例的方法: matplotlib.pyplot.legend(*args, **kwargs)

legend里面的参数比较多,有一些写的会很复杂,但这篇文章部主要讨论legend的用法。这里选择了最简单的写法,在plt.scatter() 或者 plt.plot()中 ,添加“label”项,label 参数后面的字符,即为该绘图语句对应的图例。

    plt.scatter(x, y, s = 50, color = 'k', marker = 'o',
    			label = 'Location')
    plt.scatter(x0, y0, s = 400, color = 'r',
                marker='*',label = 'Center')         
                
    plt.legend()                                      

完整程序

最后,随机生成30个坐标和始发点的坐标,(由于所用的基于basemap的程序太长,这里重新设置了30个坐标点)。10个点为一条路径。因此本程序共有三条路径。

完整程序如下(直接可以运行):

# coding=utf-8

import matplotlib.pyplot as plt
import numpy as np


def DrawPointMap():

    plt.figure()
    x0 = 5
    y0 = 5
    x = np.random.rand(30) * 10
    y = np.random.rand(30) * 10



    plt.scatter(x, y, color = 'k', marker = 'o'      # 要标记的点的坐标、大小及颜色
                ,label = 'Location')

    # annotate an important value
    plt.scatter(x0, y0, s = 200, color = 'r',
                marker='*',label = 'Center')          # 要标记的点的坐标、大小及颜色

    route1(x0, y0, x, y, plt, 0, 10, 'orange')
    route1(x0, y0, x, y, plt, 10, 20, 'darksage')
    route1(x0, y0, x, y, plt, 20, 30, 'deepskyblue')



    plt.legend()                                      # 图例
    plt.show()

# 配送路线

def route1(x0, y0, x, y, plt, N_begin, N_end,color):
    for i in range(N_begin, N_end):
        if i == N_begin:
            x_begin,y_begin = x0, y0
            x_end, y_end = x[i], y[i]
            plt_arrow(x_begin, y_begin, x_end, y_end, color)

        if i < N_end - 1:
            x_begin, y_begin = x[i], y[i]
            x_end, y_end = x[i+1], y[i+1]

        if i == N_end - 1:
            x_begin, y_begin = x[i], y[i]
            x_end, y_end = x0, y0

        plt_arrow(x_begin, y_begin, x_end, y_end, color)


def plt_arrow(x_begin,y_begin,x_end,y_end,color):

    plt.arrow(x_begin, y_begin, x_end - x_begin, y_end - y_begin,
             length_includes_head=True,     # 增加的长度包含箭头部分
             head_width = 0.3, head_length =0.5, fc=color, ec=color)

if __name__=='__main__':

    DrawPointMap()

运行结果如下:
Python 学习之 3 —— 基于basemap绘图的路径示意图

中间红星表示始发点的位置,黑色表示途径站点的位置;三个不同的颜色,表示三种不同的路径。

注意,本程序生成30个坐标点时,使用了随机生成,因此运行出来的结果跟这里贴的示意图肯定会不一样,不是程序出错了哦。