Reputation: 353
I'm finding it really difficult to achieve something that feels like it should be really simple, using matplotlib. I have a time series of 1000 data points, recorded 10s apart. I want to plot them, so that the x-axis range is correctly labelled from 0 to 10,000s. I want the y-axis values to be chosen automatically.
Whatever I try, I can't seem to get matplotlib to display any labels on the x axis other than the number of datapoints in the array (i.e. 0-1000). I have tried:
plotting twice. First letting it autoscale, then calling plt.axis() to retrieve the x and y limits, and then storing them for a second call of plt.axis([a,b,c,d]). It just plotted 0-1000. Somehow it just ignored me and reverted to 0-1000.
I tried this:
ax = plt.subplot(111)
ax.xaxis.set_data_interval(0, 10000)
also
plt.xlim(0, 10000)
to no avail, as well as many other things I've now deleted and forgotten. I can't believe I've somehow wasted hours on this now!
Can anybody help? Thanks!
Edit: I was asked for a minimal example - here are two that illustrate the two results that I have found,
import matplotlib.pyplot as plt
tseries=[1,2,3,4,5,6,7,8,9,10]
plt.plot(tseries)
ax = plt.subplot(111)
ax.xaxis.set_data_interval(0, 10000)
plt.show()
This one is just ignored
import matplotlib.pyplot as plt
tseries=[1,2,3,4,5,6,7,8,9,10]
plt.plot(tseries)
plt.xlim(0, 100)
plt.show()
And this one squashes all the data, keeping it in the 0-10 range of the plot.
All methods I have tried have produced one of the two results above
Basically I just want the first plot with the axes of the second.
Upvotes: 1
Views: 5368
Reputation: 353
Finally found a solution that works. There's probably a better way.
x = np.arange(0.0, total_time, total_time/len(tseries))
y = np.array(tseries)
plt.plot(x.flatten(),y.flatten())
Edit:
This turned out sometimes fail, saying the lengths of x and y were not the same.
I added this hack to prevent that:
if len(x)!=len(y):
l=min(len(x),len(y))
x=x[:l]
y=y[:l]
I guess it's caused by rounding errors in the "total_time/len(tseries" term when creating x.
Edit2: Mr. T has pointed out below that np.linspace() can be used to avoid the rounding error.
Upvotes: 1
Reputation: 10150
Maybe I'm misunderstanding the question, but this should be as simple as creating a X-series that contains the time values/labels you want. No need to do any limiting of the axis range:
import matplotlib.pyplot as plt
import numpy as np
import random
values = random.sample(range(0,1000), 1000)
times = np.arange(len(values)) * 10
# alternatively:
# times = np.arange(0, len(values)*10, 10)
plt.plot(times, values)
values
has your 1000 data points. you need to create another array that contains the times associated with each of your values. In your original question you didn't specify an X array, so it was just plotting your values against index (0-9)
Because you know that each value recording happened 10 seconds apart, it should be as simple as generating a 1000 item list with the values 0-1000, and then multiplying each item by 10 to get the actual "recorded" times
Upvotes: 1