简体   繁体   English

在Python中标注二维线plot与matplotlib的距离

[英]Annotating distance of 2D line plot with matplotlib in Python

Does anyone have idea, how to show distance of each point in plot. I am using matplotlib for this purpose.有谁知道如何显示 plot 中每个点的距离。为此我正在使用 matplotlib。 The distance function is already made which is working under for loop to print distance of each line segment.距离 function 已经完成,它正在 for 循环下工作以打印每个线段的距离。 But I would like to have these distances showing on each line segment plot. Any help in this regards will be appreciated.但我希望在每个线段 plot 上显示这些距离。在这方面的任何帮助将不胜感激。

from math import *

import matplotlib.pyplot as plt

import numpy as np

def DistanceBwPoints(ln1):

    x1 , y1 = ln1[0][0] , ln1[0][1]
    x2 , y2 = ln1[1][0] , ln1[1][1]

    dis = sqrt ((x2 - x1)**2 + (y2 - y1)**2 )

    return dis


def visualization2(a,b):

    x1 = []
    y1 = []
    for pt in a:
        x1 += [pt[0]]
        y1 += [pt[1]]
    plt.plot(x1,y1, 'yo')
    
    m1=[]
    m1 = range(len(x1))
    for i in np.arange(0,len(m1)-1,2):
        plt.plot(x1[i:i+2],y1[i:i+2], color=b)

my_list = [[416689.15984457487, 5961369.921824793], [416463.47437214176, 5961262.376170568], [416784.93559347134, 5961169.622417776], [416662.37786889425, 5961110.342221191], [416882.24253254064, 5960968.447021521], [416861.28136564675, 5960958.308271814]]
for i in range(0,len(my_list)-1,2):
    ln = my_list[i] , my_list[i+1]
    print(round(DistanceBwPoints(ln),2))

visualization2(my_list,'red') 
plt.axis('equal')
plt.show()

Matplotlib has the text and annotate functions to plot text into a graph. Matplotlib具有text annotate功能,可将plot文字转成图形。 In your case, text will suffice.在您的情况下, text就足够了。 In the original answer (see below), I have tried to keep your structure as much as possible but since the distances have to be calculated for the plot anyhow, I have integrated this into the plot loop to avoid code repetition.在原始答案(见下文)中,我已尝试尽可能保留您的结构,但由于必须为 plot 计算距离,我已将其集成到 plot 循环中以避免代码重复。 But the original simple approach looked weird for slopes other than ascending.但是最初的简单方法对于上升以外的斜坡看起来很奇怪。 So, here is an improved version while keeping your general structure:所以,这是一个改进的版本,同时保持你的一般结构:

from math import sqrt
import matplotlib.pyplot as plt
import numpy as np

my_list = [[1, 2], [10, 20], [30, 80], [70, 50], [110, 120], [180, 190], [130, 20], [180, 20], [10, 120], [10, 150]]
    
def DistanceBwPoints(ln1):
    x1 , y1 = ln1[0][0] , ln1[0][1]
    x2 , y2 = ln1[1][0] , ln1[1][1]    
    dis = sqrt ((x2 - x1)**2 + (y2 - y1)**2 )    
    return dis
  
def visualization2(a,b):    
    x1 = []
    y1 = []
    for pt in a:
        x1 += [pt[0]]
        y1 += [pt[1]]
    plt.plot(x1,y1, 'yo')
    
    m1 = range(len(x1))
    for i in np.arange(0,len(m1)-1,2):
        #plot line
        plt.plot(x1[i:i+2],y1[i:i+2], color=b)
        #calculate distance
        curr_dist = round(DistanceBwPoints([my_list[i], my_list[i+1]]),2)
        print(f"Line number {i//2+1} with distance", curr_dist)
        
        #determine slope direction of line to set text anchors correctly
        ln_slope = 1 + int(np.sign(np.diff(x1[i:i+2]) * np.diff(y1[i:i+2])))
        text_anchor_ha = ["left", "center", "right"][ln_slope]
        text_anchor_va = "bottom"
        #special case vertical line
        if not np.diff(x1[i:i+2]):
            text_anchor_ha, text_anchor_va = "right", "center"
        #annotate line    
        plt.text(x=np.mean(x1[i:i+2]), y=np.mean(y1[i:i+2]), s=curr_dist, ha=text_anchor_ha, va=text_anchor_va)

visualization2(my_list,'red') 
plt.axis('equal')
plt.show()

Sample output:样本 output: 在此处输入图像描述

And one more thing - I have changed from math import * .还有一件事 - 我已经from math import *改变了。 Please read here why import * is a bad idea.在此处阅读为什么import *是个坏主意。

Original answer原答案

from math import sqrt
import matplotlib.pyplot as plt
import numpy as np

def DistanceBwPoints(ln1):

    x1 , y1 = ln1[0][0] , ln1[0][1]
    x2 , y2 = ln1[1][0] , ln1[1][1]

    dis = sqrt ((x2 - x1)**2 + (y2 - y1)**2 )

    return dis


def visualization2(a,b):

    x1 = []
    y1 = []
    for pt in a:
        x1 += [pt[0]]
        y1 += [pt[1]]
    plt.plot(x1,y1, 'yo')
    
    m1 = range(len(x1))
    for i in np.arange(0,len(m1)-1,2):
        plt.plot(x1[i:i+2],y1[i:i+2], color=b)
        curr_dist = round(DistanceBwPoints([my_list[i], my_list[i+1]]),2)
        print(i, curr_dist)
        plt.text(x=np.mean(x1[i:i+2]), y=np.mean(y1[i:i+2]), s=curr_dist, ha="right", va="bottom")

my_list = [[416689.15984457487, 5961369.921824793], [416463.47437214176, 5961262.376170568], [416784.93559347134, 5961169.622417776], [416662.37786889425, 5961110.342221191], [416882.24253254064, 5960968.447021521], [416861.28136564675, 5960958.308271814]]

visualization2(my_list,'red') 
plt.axis('equal')
plt.show()

Sample output:样本 output: 在此处输入图像描述

You can build a list with distances of data points (let's say this list is x ) and another list y = [i for i in range(0, len(x)]您可以构建一个包含数据点距离的列表(假设此列表为x )和另一个列表y = [i for i in range(0, len(x)]

Then, use plt.plot(x, y)然后,使用plt.plot(x, y)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM