Matplotlib plotting in wrong order

Question:

Basically I have two arrays, one containing the values of the x-axis and the second containing the values of the y-axis. The problem is, when I do

plt.semilogy(out_samp,error_mc)

I get this

enter image description here

Which doesn’t make any sense. That is because the plot functions plots everything as it encounters in the x array, not caring whether it’s sorted in ascending order or not. How can I sort these two arrays so that the x array is sorted by increasing value and the y axis sorted in the same way so that the points are the same but the plot is connected so that it doesn’t make this mess?

Asked By: user6334462

||

Answers:

You can convert your arrays to numpy arrays, then use argsort on the first array, take the the array and sort both arrays with the argsort array.

Answered By: lint

Sort by the value of x-axis before plotting. Here is an MWE.

import itertools

x = [3, 5, 6, 1, 2]
y = [6, 7, 8, 9, 10]

lists = sorted(itertools.izip(*[x, y]))
new_x, new_y = list(itertools.izip(*lists))

# import operator
# new_x = map(operator.itemgetter(0), lists)        # [1, 2, 3, 5, 6]
# new_y = map(operator.itemgetter(1), lists)        # [9, 10, 6, 7, 8]

# Plot
import matplotlib.pylab as plt
plt.plot(new_x, new_y)
plt.show()

For small data, zip (as mentioned by other answerers) is enough.

new_x, new_y = zip(*sorted(zip(x, y)))

The result,

enter image description here

Answered By: SparkAndShine

just do this

list=zip(*sorted(zip(*(x,y))))
plt.plot(*list)

sorted function will sort according to the 1st argument i.e x values

Answered By: Eular

It is easier to zip, sort and unzip the two lists of data.

Example:

xs = [...]
ys = [...]

xs, ys = zip(*sorted(zip(xs, ys)))

plot(xs, ys)

See the zip documentation here: https://docs.python.org/3.5/library/functions.html#zip

Answered By: Hidde

I think you need to sort one array and the other array should also get sorted based on the first array. I got this solution from some other stack overflow question. Most probably this should be your solution.

out_samp,error_mc=zip(*sorted(zip(out_samp,error_mc)))

Now plot those two values, you get a correct graph.

Answered By: arjun subramannian

An alternative to sort the lists would be to use NumPy arrays and use np.sort() for sorting. The advantage with using arrays would be a vectorized operation while computing a function like y=f(x). Following is an example of plotting a normal distribution:

Without using sorted data

mu, sigma = 0, 0.1
x = np.random.normal(mu, sigma, 200)
f = 1/(sigma * np.sqrt(2 * np.pi)) *np.exp( - (x - mu)**2 / (2 * sigma**2) )
plt.plot(x,f, '-bo', ms = 2)

Output 1

enter image description here

With using np.sort() This allows straightforwardly using sorted array x while computing the normal distribution.

mu, sigma = 0, 0.1
x = np.sort(np.random.normal(mu, sigma, 200)) 
# or use x = np.random.normal(mu, sigma, 200).sort()
f = 1/(sigma * np.sqrt(2 * np.pi)) *np.exp( - (x - mu)**2 / (2 * sigma**2) )
plt.plot(x,f, '-bo', ms = 2)

Alternatively if you already have both x and y data unsorted, you may use numpy.argsort to sort them a posteriori

mu, sigma = 0, 0.1
x = np.random.normal(mu, sigma, 200)
f = 1/(sigma * np.sqrt(2 * np.pi)) *np.exp( - (x - mu)**2 / (2 * sigma**2) )
plt.plot(np.sort(x), f[np.argsort(x)], '-bo', ms = 2)

Notice that the code above uses sort() twice: first with np.sort(x) and then with f[np.argsort(x)]. The total sort() invocations can be reduced to one:

# once you have your x and f...
indices = np.argsort(x)
plt.plot(x[indices], f[indices], '-bo', ms = 2)

In both cases the output is

Output 2

enter image description here

Answered By: Sheldore
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.