Search code examples
pythonmatplotlibplotdrawing

Using matplotlib to draw a path given cartesian coordinates


I'm new to matplotlib and numpy and am trying to plot some array data to something like this:

plotting an array

but it currently looks like this:

enter image description here

My code is extremely basic but basically the image above is what I'd like to be able to do. I'm not too concerned yet with drawing gridlines but the plot should be proportional. I've looked at some examples on the mathplotlib website but can't find something similar enough. I wonder if pyplot is not the correct procedure or if my array is not formatted correctly?

import numpy as np
from matplotlib import pyplot as plt

data = [(2, 2), (3, 2), (4, 1), (4, 0), (3, 0), (3, 1), (4, 2),
        (4, 3), (4, 4), (3, 3), (3, 4), (2, 4), (2, 3), (1, 4),
        (0, 4), (0, 3), (1, 3), (0, 2), (1, 2), (0, 1), (0, 0),
        (1, 0), (1, 1), (2, 0), (2, 1)]

data = np.asarray(data)
print(data)
plt.ylim(0, 4)
plt.xlim(0, 4)
plt.axis([0, 4, 0, 4])
plt.plot(data)
plt.show()

Solution

  • To complete other answers, here is the closest I got in a reasonable amount of time to your desired output :

    import numpy as np
    from matplotlib import pyplot as plt
    
    data = [(2, 2), (3, 2), (4, 1), (4, 0), (3, 0), (3, 1), (4, 2),
            (4, 3), (4, 4), (3, 3), (3, 4), (2, 4), (2, 3), (1, 4),
            (0, 4), (0, 3), (1, 3), (0, 2), (1, 2), (0, 1), (0, 0),
            (1, 0), (1, 1), (2, 0), (2, 1)]
    
    data = np.asarray(data)
    print(data)
    
    # make axis equal and turn them off
    plt.axis('equal')
    plt.axis('off')
    
    for i in range(5):
        # horizontal and vertical background lines
        plt.plot([i,i], [0,4], linewidth=0.5, color='black')
        plt.plot([0,4], [i,i], linewidth=0.5, color='black')
    plt.plot(data[:,0], data[:,1], 'b') # line segments
    plt.scatter(data[:,0], data[:,1], c='b') # markers
    
    plt.show()
    

    Output:

    output


    Edit

    From this question, you can add numbers at each marker through plt.annotate. Just add this after plt.scatter :

    offset = np.array([0.1, 0.1])
    for i in range(data.shape[0]):
        # For each marker
        plt.annotate(str(i+1), data[i]+offset)
    

    Output:

    plot with annotations


    Edit #2:

    As a bonus, here is my attempt as getting the closest possible to the reference figure:

    import numpy as np
    from matplotlib import pyplot as plt
    
    data = [(2, 2), (3, 2), (4, 1), (4, 0), (3, 0), (3, 1), (4, 2),
            (4, 3), (4, 4), (3, 3), (3, 4), (2, 4), (2, 3), (1, 4),
            (0, 4), (0, 3), (1, 3), (0, 2), (1, 2), (0, 1), (0, 0),
            (1, 0), (1, 1), (2, 0), (2, 1)]
    
    data = np.asarray(data)
    print(data)
    
    # make axis equal and turn them off
    plt.axis('equal')
    plt.axis('off')
    
    for i in range(5):
        # horizontal and vertical background lines
        plt.plot([i,i], [0,4], linewidth=1.5, color='#b3b3b3', zorder=1)
        plt.plot([0,4], [i,i], linewidth=1.5, color='#b3b3b3', zorder=1)
    
    plt.plot(data[:,0], data[:,1], '#274b8b', linewidth=2.5, zorder=2) # line segments
    plt.scatter(data[np.arange(len(data))!=7,0], data[np.arange(len(data))!=7,1], s=60, c='#4472c4', edgecolors='#2e569c', zorder=3) # markers
    # marker for point 7 is not plotted in reference figure
    
    # Individual points numbers, not in reference figure so commented
    # offset = np.array([0.1, 0.1])
    # for i in range(data.shape[0]):
        # # For each marker
        # plt.annotate(str(i+1), data[i]+offset)
    
    for i in range(5):
        plt.annotate(str(i), [i-0.05, -0.25]) # X axis numbers
        plt.annotate(str(i), [-0.2, i-0.07]) # Y axis numbers
    
    
    plt.show()
    

    enter image description here