Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have an array of timestamps in the format (HH:MM:SS.mmmmmm) and another array of floating point numbers, each corresponding to a value in the timestamp array.

Can I plot time on the x axis and the numbers on the y-axis using Matplotlib?

I was trying to, but somehow it was only accepting arrays of floats. How can I get it to plot the time? Do I have to modify the format in any way?

Update :

This answer is outdated since matplotlib version 3.5 . The plot function now handles datetime data directly. See https://matplotlib.org/3.5.1/api/_as_gen/matplotlib.pyplot.plot_date.html

The use of plot_date is discouraged. This method exists for historic reasons and may be deprecated in the future.

datetime-like data should directly be plotted using plot.

If you need to plot plain numeric data as Matplotlib date format or need to set a timezone, call ax.xaxis.axis_date / ax.yaxis.axis_date before plot. See Axis.axis_date.

Old, outdated answer:

You must first convert your timestamps to Python datetime objects (use datetime.strptime ). Then use date2num to convert the dates to matplotlib format.

Plot the dates and values using plot_date :

import matplotlib.pyplot
import matplotlib.dates
from datetime import datetime
x_values = [datetime(2021, 11, 18, 12), datetime(2021, 11, 18, 14), datetime(2021, 11, 18, 16)]
y_values = [1.0, 3.0, 2.0]
dates = matplotlib.dates.date2num(x_values)
matplotlib.pyplot.plot_date(dates, y_values)
                will it plot the Date or just the time? I only want the time since on conversion to datetime, the year is set to 1990.
– randomThought
                Oct 15, 2009 at 19:19
                "... on conversion to datetime, the year is set to 1990": Could you please post the code you use to convert from string to datetime? Something might be wrong with the conversion. Re. the formatting of chart labels, see the date_demo1 link provided by J. K. Seppänen. The matplot lib documentation is excellent, BTW. matplotlib.sourceforge.net/index.html
– codeape
                Oct 19, 2009 at 13:53
                What about a scatter plot? I want to provide a size array to determine the size of the scatter-bubbles, but there is no equivalent scatter_date(), and no obvious/direct way to get this graph.
– dwanderson
                Oct 5, 2016 at 16:23
                The above returns a list with one object of type: matplotlib.lines.Line2D object. Now how do I use this to show the graph?
– Arindam Roychowdhury
                Jul 20, 2017 at 6:59

You can also plot the timestamp, value pairs using pyplot.plot (after parsing them from their string representation). (Tested with matplotlib versions 1.2.0 and 1.3.1.)

Example:

import datetime
import random
import matplotlib.pyplot as plt
# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]
# plot
plt.plot(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()
plt.show()

Resulting image:

# make up some data x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)] y = [i+random.gauss(0,1) for i,_ in enumerate(x)] # plot plt.scatter(x,y) # beautify the x-labels plt.gcf().autofmt_xdate() plt.show()

Produces an image similar to this:

I don't understand why this is the 5th question I've encountered where no one has actually TRIED using a scatter plot - it doesn't work. Type Error - invalid type promotion. – dwanderson Oct 5, 2016 at 16:21 @dwanderson Then, maybe you're doing something wrong. I've added an example for the scatter plot with datetime.datetime objects on the x axis to my post. – moooeeeep Oct 6, 2016 at 7:26 @AimForClarity Works for me with matplotlib.__version__ 2.2.2. The scatter plot has some overly wide x-limits set by default, though. This answer seems to provide a workaround other than manually adjusting plt.xlim(...): stackoverflow.com/a/46467896/1025391 – moooeeeep Aug 14, 2018 at 14:08

Using Matplotlib 2.0.0 and I had to add the following bit of code from Editing the date formatting of x-axis tick labels in matplotlib by Paul H.

import matplotlib.dates as mdates
myFmt = mdates.DateFormatter('%d')
ax.xaxis.set_major_formatter(myFmt)

I changed the format to (%H:%M) and the time displayed correctly.

All thanks to the community.

# make up some data x = [datetime.datetime.now() + datetime.timedelta(minutes=i) for i in range(12)] y = [i+random.gauss(0,1) for i,_ in enumerate(x)] # plot plt.plot([],[]) plt.scatter(x,y) # beautify the x-labels plt.gcf().autofmt_xdate() myFmt = mdates.DateFormatter('%H:%M') plt.gca().xaxis.set_major_formatter(myFmt) plt.show() plt.close()

This produces an image with the bubbles distributed as desired.

Doesnt work on py2.6 for me. I get ValueError: view limit minimum -0.05500000000000001 is less than 1 and is an invalid Matplotlib date value. This often happens if you pass a non-datetime value to an axis that has datetime units <Figure size 432x288 with 1 Axes> – AimForClarity Aug 14, 2018 at 10:58 A solution to the strange x-lims is to set them on your own: stackoverflow.com/questions/21423158/… – Qaswed Mar 4, 2020 at 12:31

Pandas dataframes haven't been mentioned yet. I wanted to show how these solved my datetime problem. I have datetime to the milisecond 2021-04-01 16:05:37. I am pulling linux/haproxy throughput from /proc so I can really format it however I like. This is nice for feeding data into a live graph animation.

Here's a look at the csv. (Ignore the packets per second column I'm using that in another graph)

head -2 ~/data
date,mbps,pps
2021-04-01 16:05:37,113,9342.00

By using print(dataframe.dtype) I can see how the data was read in:

(base) ➜  graphs ./throughput.py
date      object
mbps      int64
pps       float64
dtype:    object

Pandas pulls the date string in as "object", which is just type char. Using this as-is in a script:

import matplotlib.pyplot as plt
import pandas as pd
dataframe = pd.read_csv("~/data")
dates = dataframe["date"]
mbps = dataframe["mbps"]
plt.plot(dates, mbps, label="mbps")
plt.title("throughput")
plt.xlabel("time")
plt.ylabel("mbps")
plt.legend()
plt.xticks(rotation=45)
plt.show()

Matplotlib renders all the milisecond time data. I've added plt.xticks(rotation=45) to tilt the dates but it's not what I want. I can convert the date "object" to a datetime64[ns]. Which matplotlib does know how to render.

dataframe["date"] = pd.to_datetime(dataframe["date"]) 

This time my date is type datetime64[ns]

(base) ➜  graphs ./throughput.py
date    datetime64[ns]
mbps             int64
pps            float64
dtype:          object

Same script with 1 line difference.

#!/usr/bin/env python
import matplotlib.pyplot as plt
import pandas as pd
dataframe = pd.read_csv("~/data")
# convert object to datetime64[ns]
dataframe["date"] = pd.to_datetime(dataframe["date"]) 
dates = dataframe["date"]
mbps = dataframe["mbps"]
plt.plot(dates, mbps, label="mbps")
plt.title("throughput")
plt.xlabel("time")
plt.ylabel("mbps")
plt.legend()
plt.xticks(rotation=45)
plt.show()

This might not have been ideal for your usecase but it might help someone else.

This saved me a bunch of time and frustration, thanks for sharing! Any idea how to get the x-lable dates to show in format day-month-year-hour-min? – Ruben Aug 29, 2021 at 8:31 Cool! Yea create a subplot to access the xaxis attribute. This is a comment so hard to show it but from my example above add fig,ax = plt.subplots() and add date_form = DateFormatter("%d-%m-%Y-%H-%M") and ax.xaxis.set_major_formatter(date_form) before .show() – b0bu Aug 30, 2021 at 10:13