0

I am using matplotlib to plot some data and my code looks like this

import datetime                                               
import random                                            
import matplotlib.pyplot as plt 
x = [datetime.datetime.strptime(str(i), '%H') for i in range(24)]
# y is an array consists of 8640 elements for 1 day
y = [ 299.8,  299.8,  299.8, ....... 299.7,  299.7,  299.6,  299.6]
# z is an array consists of 144 elements for 1 day
z = [32, 32, 32.3, 33.54, .............31.43, 31.21, 36]

plt.plot(x,y)
plt.plot(x,z)

plt.show

but i get this error.

ValueError: x and y must have same first dimension

what i understand is that both x and y should equal length. "y" produced data every 10 seconds, so total 8640 points and "z" is the data which is produce every 10 minutes so total points 144. I look at SO and google but could not find to solve my problem. I try this one also 'plotting unix timestamps in matplotlib'

I am new to python and matplotlib. Can someone guide me how to solve this problem and to produce x-axis correctly. Thanks

Community
  • 1
  • 1
robbin
  • 313
  • 1
  • 5
  • 14
  • 1
    How is that a "weird" error? To make a plot, matplotlib needs to know the x and y coordinate of every point to mark on the axes. If x and y are different lengths, you don't have an (x, y) coordinate pair for every point, so it can't make the plot. You probably need to subsample `x` to the same time intervals that your `y` and `z` arrays are sampled at – tmdavison May 17 '17 at 14:46
  • @tom subsample but how? . because "y" data points are produced every 10 seconds and "z" are produced every 10 minutes. Can you show me an example. .thanks a lot – robbin May 17 '17 at 14:50
  • 1
    `plt.plot(x, y)` is fine but your `x` does not make sense. It should contain the timestamp of every element in `y`. The same goes for plotting `z`. Here you need a different `x` with the timestams of the elements in `z`. – MB-F May 17 '17 at 14:59
  • @kazemakase thanks a lot. Can you help me and show an example. my "y" contains 3000 data points for one day and "z" contains 1000 data points. How can I make x accordingly to solve my problem. – robbin May 17 '17 at 15:04
  • @robbin Try the easy way first: `xy = np.linspace(0, 1, 3000)` and `xz = np.linspace(0, 1, 1000)`. (3000/1000 points seems inconsistent with your question where you state 1000+/500) – MB-F May 17 '17 at 15:10
  • @robbin Think of the problem independent of a computer: Having a list of values for the xaxis and one for the yaxis, how would you draw a graph, using pen and paper, if both lists have different number of elements? It's simply not possible. Once you have become clear about what you want to accomplish, one might of course help you doing that with matplotlib, but as it stands, you need to first solve the problem on your side. – ImportanceOfBeingErnest May 17 '17 at 16:16
  • @ImportanceOfBeingErnest I understand the problem. I don't know how to produce 8640 time data points on x-axis and same method then i can apply for z which consists of 144 points on x-axis. I mean I am unable to produce x-axis time points which are in seconds and in minutes. – robbin May 17 '17 at 16:22
  • @robbin have you tried using pandas? pandas.date_range(start=pd.datetime.today(), periods=10, freq='H').tolist(). This gives you timestamps every minute. – Daan May 17 '17 at 16:42
  • @DaanVanHauwermeiren No I did not try pandas. I will give it a try. Can you show me some example in pandas related to my question. I am new to pandas too. Thanks a lot – robbin May 17 '17 at 16:47

1 Answers1

1

pandas is pretty handy to tackle dates and ranges of dates:

Get a date range between May 17th 2017 and May 18th 2017, with frequency hours or seconds:

pd.date_range(start='2017 05 17', end='2017 05 18', freq='H')
pd.date_range(start='2017 05 17', end='2017 05 18', freq='s')

or the other option is to start from a certain time, specify the frequency (in this example hours), and the number of periods you need

pd.date_range(start='2017 05 17', periods=15, freq='H')
Daan
  • 940
  • 10
  • 22