Search code examples
pythonpython-3.xmatplotlibvector-graphics

How to plot a directed line segment (vector) given 2 points (Latitude and longitude) in Matplotlib


Imagine that we start from a Python list like:

list=[[-3.7025753,40.417016,-3.7062202, 40.4285271, 20], [5.7023456,40.221567,3.67823, 41.27236, 10]]

Where:

  • First element is longitude of point A (Ex. in first element of the list: -3.7025753)
  • Second element is latitude of point A (Ex. in first element of the list: 40.417016)
  • Third element is longitude of point B (Ex. in first element of the list: -3.7062202)
  • Fouth element is longitude of point B (Ex. in first element of the list: 40.4285271)
  • Fifth element is a magnitude (Ex. in first element of the list: 20)

What I'm trying to obtain in Matplotlib is a plot similar to:

Expected Plot

Summarizing:

  1. Plotting points is clear with plot(x, y)
  2. Plotting labels also clear with Text function of Matplotlib
  3. The key pending Things that I'm asking are:
  • 3.1 How to plot a line in the origin dot "oriented" to the target or destiny dot?

According to first answer the function to be used shoould be:

 matplotlib.pyplot.arrow(x, y, dx, dy, **kwargs)

The point is that this function receives, apart from de x and y origing corrdinates, the delta dx and dy. In my problem point B provides me the direction of the vector and the size needs to be proportional to its magnitude. So the main question is How I can transform data from (latitude_origin, longitude_origin, latitude_destiny, longitude_destiny, magnitude) to (x, y, dx, dy)?. Understanding that x, y has a direct transformation from latitude and longitude origin, but what about dx and dy?


Solution

  • Finally I found a solution:

    Step 1: Calculate the angle in grades that forms the line that joins origing and destiny. Using this custom function:

    import math
    
    def CalcPendAng (lon1, lat1, lon2,lat2):
    
        if (lon2-lon1)==0:
            ang_grad=0 división por 0
        else:    
            m=(lat2-lat1) / (lon2-lon1)
            ang_rad=math.atan(m) 
            ang_grad=ang_rad* 180 / 3.14159265
    
        return ang_grad
    

    Step 2 Calculat the destiny poit that is in the sme line that joins origin and destiny but with a distance to te origin ponit = module of teh vector we want:

    def CalcLatLonDest (lon1, lat1,modulo, angulo_grad):
    
        factor_corrector= 0.0001
    
        lon2= lon1 + (modulo* math.cos(angulo_grad))
        lat2= lat1 + (modulo* math.sin(angulo_grad))
       
        return lon2, lat2