【问题标题】:How can draw a line in matplotlib so that the edge (not the center) of the drawn line follows the plotted data?如何在 matplotlib 中绘制一条线,以便绘制线的边缘(而不是中心)跟随绘制的数据?
【发布时间】:2013-01-25 19:14:29
【问题描述】:

我正在制作一个图形,以在高速公路地图上显示交通水平。这个想法是,对于每个 高速公路段,我会绘制两条线 - 一条用于方向。每一层的厚度 线 将对应于该方向的交通量。我需要绘制线条 以便绘制线的左边缘(相对于行驶方向)跟随 高速公路路段的形状。我想在数据坐标中指定形状, 但我想以点为单位指定线的粗细。

我的数据是这样的:

[[((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) 是交通量分别是正向和反向的体积

看起来很重要:结果应该很漂亮。

【问题讨论】:

    标签: data-visualization python matplotlib


    【解决方案1】:

    我想出了一个使用matplotlib.transforms.Transformshapely.geometry.LineString.parallel_offset 的解决方案。

    请注意,shapely 的 parallel_offset 方法有时会返回 MultiLineString,这 此代码不处理。我已经改变了第二个形状,所以它不会交叉自己以避免这个问题。我认为这个问题在我的应用程序中很少发生。

    另一个注意事项: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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      • 1970-01-01
      • 2011-01-19
      • 1970-01-01
      相关资源
      最近更新 更多