I'm trying to format my X axis dates in a Django application where I'm returning the graph in memory in a response object. I followed the same example that I already use in an ipython notebook, and do this:
def pretty_date(date):
log.info("HELLO!")
return date.strftime("%c")
def image_calls(request):
log.info("in image_loadavg")
datetimes = []
calls = []
for m in TugMetrics.objects.all():
datetimes.append(m.stamp)
calls.append(m.active_calls)
plt.plot(datetimes, calls, 'b-o')
plt.grid(True)
plt.title("Active calls")
plt.ylabel("Calls")
plt.xlabel("Time")
fig = plt.gcf()
fig.set_size_inches(8, 6)
fig.autofmt_xdate()
axes = plt.gca()
#axes.fmt_xdata = mdates.DateFormatter("%w %H:%M:%S")
axes.fmt_xdata = pretty_date
buf = io.BytesIO()
fig.savefig(buf, format='png', dpi=100)
buf.seek(0)
return HttpResponse(buf, content_type='image/png')
The graph is returned but I seem to have no control over how to X axis looks, and my HELLO! log is never called. Note that the m.stamp is a datetime object.
This works fine in ipython notebook, both running matplotlib 1.4.2.
Help appreciated.
The issue actually stems from the matplotlib backend not being properly set, or from a missing dependency when compiling and installing matplotlib.
To switch axes in matplotlib, we can create a figure and add two subplots using subplots() method. Plot curves, extract x and y data, and set these data in a second plotted curve.
axes.fmt_xdata
controls the coordinates that are interactively displayed in the lower right-hand corner of the toolbar when you mouse over the plot. It's never being called because you're not making an interactive plot using a gui backend.
What you want is ax.xaxis.set_major_formatter(formatter)
. Also, if you'd just like a default date formatter, you can use ax.xaxis_date()
.
As a quick example based on your code (with random data):
import datetime as dt
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
time = mdates.drange(dt.datetime(2014, 12, 20), dt.datetime(2015, 1, 2),
dt.timedelta(hours=2))
y = np.random.normal(0, 1, time.size).cumsum()
y -= y.min()
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(time, y, 'bo-')
ax.set(title='Active Calls', ylabel='Calls', xlabel='Time')
ax.grid()
ax.xaxis.set_major_formatter(mdates.DateFormatter("%w %H:%M:%S"))
fig.autofmt_xdate() # In this case, it just rotates the tick labels
plt.show()
And if you'd prefer the default date formatter:
import datetime as dt
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
time = mdates.drange(dt.datetime(2014, 12, 20), dt.datetime(2015, 1, 2),
dt.timedelta(hours=2))
y = np.random.normal(0, 1, time.size).cumsum()
y -= y.min()
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(time, y, 'bo-')
ax.set(title='Active Calls', ylabel='Calls', xlabel='Time')
ax.grid()
ax.xaxis_date() # Default date formatter
fig.autofmt_xdate()
plt.show()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With