车辆路径规划问题的研究一般较常遇到需要画出车辆路径示意图,已知有每辆车的真实坐标序列,那么如何利用在一个空白的坐标轴上画出路径呢?

1.准备

1.1 matplotlib引入

一般情况下只引入plt就行了,但是我这里因为要修改图例的字体,直接将matplotlib也引入进来:

import matplotlib
import matplotlib.pyplot as plt

1.2 数据形式

我的数据形式是一个三维数组,最外层包含若干车辆,车辆包含若干乘客,乘客的位置用数组[纬度,经度]表示。

schedule = [[[30.612542, 104.124815], [30.612542, 104.124815]],[[30.664593, 104.027993], [30.691008, 104.039441]]]

如果采用真实坐标,尺度太小会导致箭头粗细、标志大小的调整问题,所以我在后面画图的过程中都采取真实坐标*10的表示。

2.画图

我的问题是需要有发车点和终点的,所以需要先用以下代码标出发车点,如果没有单独发车点,或已经包含在前面的数组内,可以直接循环画图。for循环对每辆车的路径画图,应包含两个部分:画出点,在点之间用箭头连线。

2.1 画出散点

用scatter方法可以画出散点图,如果需要对每一辆车标注图例,可以调整参数,方法的参数设置可以参见:scatter方法官方文档

Python路径规划 python路径规划建模_图例

plt.scatter(x0, y0, s = 200, color = 'k',
                marker='*',label = u'机场')

*如果需要显示中文图例,并设置中文字体大小,可以在文件开始设置字体并在每一个中文字符串前加u:

#引入中文字体
myfont = matplotlib.font_manager.FontProperties(fname='C:/Windows/Fonts/simsun.ttc',size=7)
#使用中文字体
plt.scatter(x0, y0, s = 200, color = 'k',
                marker='*',label = u'机场')
#设置图例
 plt.legend(bbox_to_anchor=(1.05, 0), loc=3, borderaxespad=0,prop=myfont)

2.2 画出箭头连线

用plt.arrow()方法画出箭头连线,具体方法参见:arrow方法官方文档

def route1(x0, y0, car, plt):
    plt_arrow(x0, y0, car[0][0]*10, car[0][1]*10)
    for i in range(len(car)-1):
        plt_arrow(car[i][0]*10, car[i][1]*10, car[i+1][0]*10,car[i+1][1]*10)
    plt_arrow(car[-1][0]*10, car[-1][1]*10, x0, y0)

def plt_arrow(x_begin,y_begin,x_end,y_end):
    plt.arrow(x_begin, y_begin, x_end - x_begin, y_end - y_begin,
             length_includes_head=True,     
             head_width = 0.01, head_length =0.02, fc="black", ec="black",linestyle=line[np.random.randint(1,4)],linewidth=0.001)

2.3 完整代码

# coding=utf-8
import matplotlib
import matplotlib.pyplot as plt
import numpy as np

#显示中文
myfont = matplotlib.font_manager.FontProperties(fname='C:/Windows/Fonts/simsun.ttc',size=7)

#点和线的形状集合
line = ['-','--','-.',':']
point = ['.',',','o','v','^','<','>','1','2','3','4','s','p','*','h','H','+','x','D','d','|','_','x','P','X','8']
schedule = [[[30.612542, 104.124815], [30.612542, 104.124815], [30.655155, 104.130167], [30.65551, 104.128293], [30.664906, 104.123196], [30.655029, 104.102768], [30.641632, 104.111138]], [[30.655078, 104.089894], [30.655078, 104.089894], [30.659934, 104.080402], [30.675628, 104.080586], [30.693483, 104.089597], [30.665345, 104.077832], [30.679517, 104.050707]]]

def DrawPointMap():

    plt.figure()
    x0 = 30.584035 * 10
    y0 = 103.967432 * 10


    plt.scatter(x0, y0, s = 200, color = 'k',
                marker='*',label = u'机场')
    # annotate an important value
    for i in range(len(schedule)):
        x = []
        y = []
        for location in schedule[i]:
            x.append(location[0]*10)
            y.append(location[1]*10)
        plt.scatter(x, y, color='k', marker=point.pop()  # 要标记的点的坐标、大小及颜色
                , label=(u'车辆'+ str(i+1)))
        route1(x0, y0, schedule[i], plt)


    plt.legend(bbox_to_anchor=(1.05, 0), loc=3, borderaxespad=0,prop=myfont)    # 图例
    x = [305.8,306.0,306.2,306.4,306.6,306.8,307.0,307.2]
    plt.xticks(x,( '30.58', '30.60', '30.62', '30.64', '30.66', '30.68', '30.70', '30.72'))
    y = [1039.50, 1039.75, 1040.00, 1040.25, 1040.50, 1040.75, 1041.00, 1041.25, 1041.50]
    plt.yticks(y, ('103.950', '103.9750', '104.000', '104.025', '104.050', '104.075', '104.100', '104.125', '104.150'))
    plt.show()

# 配送路线

def route1(x0, y0, car, plt):
    plt_arrow(x0, y0, car[0][0]*10, car[0][1]*10)
    for i in range(len(car)-1):
        plt_arrow(car[i][0]*10, car[i][1]*10, car[i+1][0]*10,car[i+1][1]*10)
    plt_arrow(car[-1][0]*10, car[-1][1]*10, x0, y0)




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

    plt.arrow(x_begin, y_begin, x_end - x_begin, y_end - y_begin,
             length_includes_head=True,     # 增加的长度包含箭头部分
             head_width = 0.01, head_length =0.02, fc="black", ec="black",linestyle=line[np.random.randint(1,4)],linewidth=0.001)

if __name__=='__main__':
    DrawPointMap()

最终就得到我们想要的图啦:

Python路径规划 python路径规划建模_中文字体_02