1

高速道路の地図に交通量を表示する図を作成しています。アイデアは、高速道路のセグメントごとに 2 本の線をプロットするというものです。1 本は方向です。各線の太さは、その方向の交通量に対応します。描画された線の左端 (進行方向に対して) が高速道路セグメントの形状に従うように、線をプロットする必要があります。形状はデータ座標で指定したいのですが、線の太さはポイントで指定したいです。

私のデータは次のようなものです:

[[((5,10),(-7,2),(8,9)),(210,320)],
 [((8,4),(9,1),(8,1),(11,4)),(2000,1900)],
 [((12,14),(17,14)),(550,650)]]

ここで、たとえば、((5,10),(-7,2),(8,9)) は高速道路セグメントの形状を表す x、y 値のシーケンスであり、(210,320) は道路の交通量です。それぞれ順方向と逆方向

見た目は重要です。結果はきれいでなければなりません。

4

1 に答える 1

0

matplotlib.transforms.Transformshapely.geometry.LineString.parallel_offsetを使用して解決策を見つけました。

shapelyのメソッドは、このコードでは処理されないをparallel_offset返す場合があることに注意してください。MultiLineStringこの問題を回避するために、2番目の形状が交差しないように変更しました。私のアプリケーションでは、この問題はめったに起こらないと思います。

別の注意:matplotlib.transforms.Transformのドキュメントは、メソッドによって返される配列が引数として渡される配列と同じ形状でなければならないことを示唆しているようですがtransform、メソッドにプロットするポイントを追加すると、transformここで機能するようです。

#matplotlib version 1.1.0
#shapely version 1.2.14
#Python 2.7.3

import matplotlib.pyplot as plt
import shapely.geometry
import numpy
import matplotlib.transforms


def get_my_transform(offset_points, fig):
    offset_inches = offset_points / 72.0
    offset_dots = offset_inches * fig.dpi

    class my_transform(matplotlib.transforms.Transform):        

        input_dims = 2
        output_dims = 2
        is_separable = False
        has_inverse = False

        def transform(self, values):
            l = shapely.geometry.LineString(values)
            l = l.parallel_offset(offset_dots,'right')
            return numpy.array(l.xy).T

    return my_transform()


def plot_to_right(ax, x,y,linewidth, **args):

    t = ax.transData + get_my_transform(linewidth/2.0,ax.figure)

    ax.plot(x,y, transform = t,
            linewidth = linewidth,
            solid_capstyle = 'butt',
            **args)


data = [[((5,10),(-7,2),(8,9)),(210,320)],
 [((8,4),(9,1),(8,1),(1,4)),(2000,1900)],
 [((12,14),(17,16)),(550,650)]]


fig = plt.figure()
ax = fig.add_subplot(111)


for shape, volumes in data:

    x,y = zip(*shape)
    plot_to_right(ax, x,y, volumes[0]/100., c = 'blue')
    plot_to_right(ax, x[-1::-1],y[-1::-1], volumes[1]/100., c = 'green')
    ax.plot(x,y, c = 'grey', linewidth = 1)


plt.show()
plt.close()
于 2013-01-28T16:48:12.567 に答える