0

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?

7
  • 1
    Not sure what you mean by "recommended way", but most often people use arrows to indicate direction. Commented Dec 3, 2017 at 14:55
  • @ImportanceOfBeingErnest Okay, how do you do that? I'm not seeing any mention of arrows in the list of available markers. Commented Dec 3, 2017 at 15:09
  • 1
    Well there are some markers that could be used like "^", "<" etc. in which case you need to know the direction beforehands and choose the corresponding marker such that it points in the correct direction. Or instead of a line you draw an arrow unsing FancyArrowPatch. The question is not detailed enough for me to know what exactly you want your plot to look like. Commented Dec 3, 2017 at 16:03
  • @ImportanceOfBeingErnest I don't care exactly what it looks like, but I need a solution that works even though I don't know the correct direction beforehand. What I've got at the moment is marking the beginning of the line with a red marker and the end with a blue marker, but I'd like something more transparent. Even if there's a way to just use the words 'begin' and 'end' or suchlike, that would be an improvement. Commented Dec 3, 2017 at 17:02
  • 1
    I like this simple solution using quiver: stackoverflow.com/questions/7519467/… Commented Jan 13, 2020 at 19:34

1 Answer 1

4

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.