rwallace
rwallace

Reputation: 33525

How to plot a directed line in matplotlib?

In matplotlib, it's easy to draw a line from data points with plt.plot(xs, ys, '-'+marker). This gets you an undirected line, where you can't tell from looking at the resulting diagram, which end corresponds to the beginning of the arrays of data points and which to the end of the arrays. It happens that for what I'm doing, it's important to be able to tell which end is which, or equivalently, which direction the line is going. What is the recommended way to plot a line so as to obtain that visual distinction?

Upvotes: 0

Views: 2874

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339695

The following would be one option. It is to add some arrow heads along a line. This can be done using a FancyArrowPatch.

import numpy as np ; np.random.seed(7)
import matplotlib.pyplot as plt
from matplotlib.patches import FancyArrowPatch 

class RL(object):
    def __init__(self, n, d, s=0.1):
        a = np.random.randn(n)*s
        a[0] = np.random.rand(1)*np.pi*2
        self.xy = np.random.rand(n,2)*5
        self.xy[1,:] = self.xy[0,:] + np.array([d*np.cos(a[0]),d*np.sin(a[0])])
        for i in range(2,n):
            (x,y), = np.diff(self.xy[i-2:i,:], axis=0)
            na = np.arctan2(y,x)+a[i]
            self.xy[i,:] = self.xy[i-1,:] + np.array([d*np.cos(na),d*np.sin(na)])
        self.x = self.xy[:,0]; self.y = self.xy[:,1]

l1 = RL(1000,0.005)
l2 = RL(1000,0.007)
l3 = RL(1000,0.005)

fig, ax = plt.subplots()
ax.set_aspect("equal")
ax.plot(l1.x, l1.y)
ax.plot(l2.x, l2.y)
ax.plot(l3.x, l3.y)
ax.plot(l1.x[0], l1.y[0], marker="o")

def arrow(x,y,ax,n):
    d = len(x)//(n+1)    
    ind = np.arange(d,len(x),d)
    for i in ind:
        ar = FancyArrowPatch ((x[i-1],y[i-1]),(x[i],y[i]), 
                              arrowstyle='->', mutation_scale=20)
        ax.add_patch(ar)

arrow(l1.x,l1.y,ax,3)
arrow(l2.x,l2.y,ax,6)
arrow(l3.x,l3.y,ax,10)

plt.show()

enter image description here

Upvotes: 4

Related Questions