Plotting a list of (x, y) coordinates in matplotlib

Question:

I have a list of pairs (a, b) that I would like to plot with matplotlib in python as actual x-y coordinates. Currently, it is making two plots, where the index of the list gives the x-coordinate, and the first plot’s y values are the as in the pairs and the second plot’s y values are the bs in the pairs.

To clarify, my data looks like this: li = [(a,b), (c,d), ... , (t, u)] and I want to do a one-liner that just calls plt.plot().
If I didn’t require a one-liner I could trivially do:

xs = [x[0] for x in li]
ys = [x[1] for x in li]
plt.plot(xs, ys)

How can I get matplotlib to plot these pairs as x-y coordinates?


Sample data

# sample data
li = list(zip(range(1, 14), range(14, 27)))

li → [(1, 14), (2, 15), (3, 16), (4, 17), (5, 18), (6, 19), (7, 20), (8, 21), (9, 22), (10, 23), (11, 24), (12, 25), (13, 26)]

Incorrect Plot

plt.plot(li)
plt.title('Incorrect Plot:nEach index of the tuple plotted as separate lines')

enter image description here

Desired Plot

This produces the correct plot, but to many lines of code are used to unpack li. I need to unpack and plot with a single line of code, not multiple list-comprehensions.

xs = [x[0] for x in li]
ys = [x[1] for x in li]
plt.plot(xs, ys)
plt.title('Correct Plot:nBut uses to many lines to unpack li')

enter image description here

Asked By: CodeKingPlusPlus

||

Answers:

Given li in the question:

li = list(zip(range(1, 14), range(14, 27)))

To unpack the data from pairs into lists use zip:

x, y = zip(*li)

x → (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
y → (14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26)

The one-liner uses the unpacking operator (*), to unpack the list of tuples for zip, and unpacks the zip object into the plot API.

plt.scatter(*zip(*li))

enter image description here

plt.plot(*zip(*li))

enter image description here

Answered By: sashkello

If you want to plot a single line connecting all the points in the list

plt.plot(li[:])

plt.show()

This will plot a line connecting all the pairs in the list as points on a Cartesian plane from the starting of the list to the end.
I hope that this is what you wanted.

Answered By: Shubham Rana

If you have a numpy array you can do this:

import numpy as np
from matplotlib import pyplot as plt

data = np.array([
    [1, 2],
    [2, 3],
    [3, 6],
])
x, y = data.T
plt.scatter(x,y)
plt.show()
Answered By: Zweedeend

Matplotlib’s plot or scatter or any of the plotting methods take x-axis values as the first argument, y-axis values as the second argument and matches on the coordinate plane by index; so the first element passed as x-axis value and the first element passed as y-axis value correspond to the x-y coordinate of the first point, etc.

When you have a list or a numpy array of coordinates such as:

li = [(1, 14), (2, 15), (3, 16), (4, 17), (5, 18), (6, 19)]
# or 
arr = np.array([[1, 14], [2, 15], [3, 16], [4, 17], [5, 18], [6, 19]])

when you transpose them, using zip(*li) or arr.T, you create the x-axis and y-axis values. Then when you pass them off to plot() or scatter() call, you’re passing them as positional arguments (*args).

import matplotlib.pyplot as plt
plt.scatter(*zip(*li));
# or
plt.scatter(*arr.T);

As with any Python function call, you can pass more arguments either by position or as keyword. For example, if you want to change the size of the dots in a scatter plot, you can do so by passing s=:

plt.scatter(*arr.T, s=100);

Also, you can plot a scatter plot (x-y coordinates on a map) using a plot call as well. All you have to do is pass a circle (o) or a point (.) marker (which happens to be the third positional argument).

plt.plot(*zip(*li), 'o');
# or
plt.plot(*arr.T, '.');

You can also set the color of the plot together with the marker. For example, plt.plot(*arr.T, 'ko') plots scatter plots with black circles.

Answered By: cottontail