How to plot data against specific dates on the x-axis using matplotlib


Question

I have a dataset consisting of date-value pairs. I want to plot them in a bar graph with the specific dates in the x-axis.

My problem is that matplotlib distributes the xticks over the entire date range; and also plots the data using points.

The dates are all datetime objects. Here's a sample of the dataset:

data = [(DT.datetime.strptime('2010-02-05', "%Y-%m-%d"), 123),
        (DT.datetime.strptime('2010-02-19', "%Y-%m-%d"), 678),
        (DT.datetime.strptime('2010-03-05', "%Y-%m-%d"), 987),
        (DT.datetime.strptime('2010-03-19', "%Y-%m-%d"), 345)]

Here is a runnable code sample using pyplot

import datetime as DT
from matplotlib import pyplot as plt

data = [(DT.datetime.strptime('2010-02-05', "%Y-%m-%d"), 123),
        (DT.datetime.strptime('2010-02-19', "%Y-%m-%d"), 678),
        (DT.datetime.strptime('2010-03-05', "%Y-%m-%d"), 987),
        (DT.datetime.strptime('2010-03-19', "%Y-%m-%d"), 345)]

x = [date for (date, value) in data]
y = [value for (date, value) in data]

fig = plt.figure()

graph = fig.add_subplot(111)
graph.plot_date(x,y)

plt.show()

QUESTION SUMMARY:
My situation is more like I have an Axes instance ready (referenced by graph in the code above) and I want to do the following:

  1. Make the xticks correspond to the exact date values. I have heard of matplotlib.dates.DateLocator but I have no idea how create one and then associate it with a specific Axes object.
  2. Get tighter control over the type of graph being used (bar, line, points, etc.)
1
17
6/18/2014 3:19:49 PM

Accepted Answer

What you're doing is simple enough that it's easiest to just using plot, rather than plot_date. plot_date is great for more complex cases, but setting up what you need can be easily accomplished without it.

e.g., Based on your example above:

import datetime as DT
from matplotlib import pyplot as plt
from matplotlib.dates import date2num

data = [(DT.datetime.strptime('2010-02-05', "%Y-%m-%d"), 123),
        (DT.datetime.strptime('2010-02-19', "%Y-%m-%d"), 678),
        (DT.datetime.strptime('2010-03-05', "%Y-%m-%d"), 987),
        (DT.datetime.strptime('2010-03-19', "%Y-%m-%d"), 345)]

x = [date2num(date) for (date, value) in data]
y = [value for (date, value) in data]

fig = plt.figure()

graph = fig.add_subplot(111)

# Plot the data as a red line with round markers
graph.plot(x,y,'r-o')

# Set the xtick locations to correspond to just the dates you entered.
graph.set_xticks(x)

# Set the xtick labels to correspond to just the dates you entered.
graph.set_xticklabels(
        [date.strftime("%Y-%m-%d") for (date, value) in data]
        )

plt.show()

If you'd prefer a bar plot, just use plt.bar(). To understand how to set the line and marker styles, see plt.plot() Plot with date labels at marker locations http://www.geology.wisc.edu/~jkington/matplotlib_date_labels.png

30
8/15/2010 3:31:38 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon