Time axis for imshow

Hello,

Is there any easy way to specify a time-axis using imshow to plot 2D data?

Thanks.

···


Gökhan

Sure, just call “ax.xaxis_date()” (or “yaxis_date”, depending on which axis you want to represent a date).

As a quick example:

import matplotlib.pyplot as plt

import matplotlib.dates as mdates
import numpy as np

Generate data…

ny = 100
xmin, xmax = mdates.datestr2num([‘01/01/2011’, ‘11/10/2011’])
data = np.random.random((ny, int(xmax-xmin)+1)) - 0.5

data = data.cumsum(axis=1)

Plot…

fig, ax = plt.subplots()
ax.imshow(data, extent=[xmin, xmax, 0, ny])
ax.xaxis_date()
fig.autofmt_xdate()

plt.show()

Cheers,

-Joe

···

On Wed, Nov 9, 2011 at 11:45 PM, Gökhan Sever <gokhansever@…287…> wrote:

Hello,

Is there any easy way to specify a time-axis using imshow to plot 2D data?

Thanks Joe,

I forgot to convert my numeric time array into a form that mpl can understand.

I198 time

O198

array([ 32643.78595805, 32643.82032609, 32643.85445309, …,

32871.46535802, 32871.49946594, 32871.53384495])

I199 ncnt

O199

array([0001-01-01 09:04:03+00:00, 0001-01-01 09:04:03+00:00,

0001-01-01 09:04:03+00:00, …, 0001-01-01 09:07:51+00:00,

0001-01-01 09:07:51+00:00, 0001-01-01 09:07:51+00:00], dtype=object)

Although, this doesn’t give me millisecond precision. Is there any way to get ms precision via datetime module?

This is not a matter for plotting, since second precision is good enough for eyes.

Then setting extent properly and either calling ax.xaxis_date or calling setters manually

I196 xmin = mdates.date2num(ncnt[0])

I197 xmax = mdates.date2num(ncnt[-1])

plt.imshow(z.T, interpolation=‘nearest’, aspect=‘auto’, origin=‘lower’, extent=[xmin, xmax, 0, z.shape[1]])

ax = plt.gca()

ax.xaxis.set_major_formatter(DateFormatter(‘%H:%M:%S’))

ax.xaxis.set_major_locator(SecondLocator(interval=30))

ax.xaxis.set_minor_locator(SecondLocator(interval=5))

gives me better control over the major/minor ticks.

···

On Thu, Nov 10, 2011 at 8:15 AM, Joe Kington <jkington@…150…> wrote:

On Wed, Nov 9, 2011 at 11:45 PM, Gökhan Sever <gokhansever@…287…> wrote:

Hello,

Is there any easy way to specify a time-axis using imshow to plot 2D data?

Sure, just call “ax.xaxis_date()” (or “yaxis_date”, depending on which axis you want to represent a date).

As a quick example:

import matplotlib.pyplot as plt

import matplotlib.dates as mdates
import numpy as np

Generate data…

ny = 100
xmin, xmax = mdates.datestr2num([‘01/01/2011’, ‘11/10/2011’])
data = np.random.random((ny, int(xmax-xmin)+1)) - 0.5

data = data.cumsum(axis=1)

Plot…

fig, ax = plt.subplots()
ax.imshow(data, extent=[xmin, xmax, 0, ny])
ax.xaxis_date()
fig.autofmt_xdate()

plt.show()

Cheers,

-Joe


RSA(R) Conference 2012

Save $700 by Nov 18

Register now

http://p.sf.net/sfu/rsa-sfdev2dev1


Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users


Gökhan

Although, this doesn’t give me millisecond precision. Is there any way to get ms precision via datetime module?

Well, datetime objects, matplotlib’s internal float dates, and numpy datetime64 objects all support microsecond resolution.

However matplotlib’s locator rules can’t handle microsecond or millisecond resolution. There aren’t any locators for less than second resolution.

Also, imshow sets the aspect of the plot to 1 by default, which is probably why you’re having to set the extents manually. If you specify “aspect=‘auto’” in the imshow call you can avoid that step. (However, strange things happen when the span of the extents drops below 100 microseconds… I’m guessing something is being cast to float32’s somewhere?)

As a quick example to demonstrate using sub-second resolution (without a proper tick locator):

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates

from datetime import datetime

Generate data…

ny = 100

nx = 100
xmin, xmax = mdates.date2num([datetime(2011, 01, 01, microsecond=1),
datetime(2011, 01, 01, microsecond=nx)])
data = np.random.random((ny, nx)) - 0.5
data = data.cumsum(axis=1)

Plot…

fig, ax = plt.subplots()
ax.imshow(data, aspect=‘auto’, extent=[xmin, xmax, 0, ny])
ax.xaxis_date()

plt.show()

At any rate, you can write a quick-and-dirty millisecond locator… Give me a bit and I’ll cobble one together. (It’s turning out to be slightly more complex than I thought…)

···

On Thu, Nov 10, 2011 at 10:06 AM, Gökhan Sever <gokhansever@…287…> wrote:

Thanks Joe,

I forgot to convert my numeric time array into a form that mpl can understand.

I198 time

O198

array([ 32643.78595805, 32643.82032609, 32643.85445309, …,

32871.46535802, 32871.49946594, 32871.53384495])

I199 ncnt

O199

array([0001-01-01 09:04:03+00:00, 0001-01-01 09:04:03+00:00,

0001-01-01 09:04:03+00:00, …, 0001-01-01 09:07:51+00:00,

0001-01-01 09:07:51+00:00, 0001-01-01 09:07:51+00:00], dtype=object)

Although, this doesn’t give me millisecond precision. Is there any way to get ms precision via datetime module?

This is not a matter for plotting, since second precision is good enough for eyes.

Then setting extent properly and either calling ax.xaxis_date or calling setters manually

I196 xmin = mdates.date2num(ncnt[0])

I197 xmax = mdates.date2num(ncnt[-1])

plt.imshow(z.T, interpolation=‘nearest’, aspect=‘auto’, origin=‘lower’, extent=[xmin, xmax, 0, z.shape[1]])

ax = plt.gca()

ax.xaxis.set_major_formatter(DateFormatter(‘%H:%M:%S’))

ax.xaxis.set_major_locator(SecondLocator(interval=30))

ax.xaxis.set_minor_locator(SecondLocator(interval=5))

gives me better control over the major/minor ticks.

On Thu, Nov 10, 2011 at 8:15 AM, Joe Kington <jkington@…150…> wrote:

On Wed, Nov 9, 2011 at 11:45 PM, Gökhan Sever <gokhansever@…287…> wrote:

Hello,

Is there any easy way to specify a time-axis using imshow to plot 2D data?

Sure, just call “ax.xaxis_date()” (or “yaxis_date”, depending on which axis you want to represent a date).

As a quick example:

import matplotlib.pyplot as plt

import matplotlib.dates as mdates
import numpy as np

Generate data…

ny = 100
xmin, xmax = mdates.datestr2num([‘01/01/2011’, ‘11/10/2011’])
data = np.random.random((ny, int(xmax-xmin)+1)) - 0.5

data = data.cumsum(axis=1)

Plot…

fig, ax = plt.subplots()
ax.imshow(data, extent=[xmin, xmax, 0, ny])
ax.xaxis_date()
fig.autofmt_xdate()

plt.show()

Cheers,

-Joe


RSA(R) Conference 2012

Save $700 by Nov 18

Register now

http://p.sf.net/sfu/rsa-sfdev2dev1


Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users


Gökhan

Although, this doesn’t give me millisecond precision. Is there any way to get ms precision via datetime module?

Well, datetime objects, matplotlib’s internal float dates, and numpy datetime64 objects all support microsecond resolution.

I260 ncnt = np.array([num2date(1 + time[j]/86400.0) for j in range(len(time))])

I261 time[0]

O261 32643.785958051682

I262 ncnt[0]

O262 datetime.datetime(1, 1, 1, 9, 4, 3, 785958, tzinfo=<matplotlib.dates._UTC object at 0x2da2610>)

int conversion for time[j] was eating my milliseconds. Now it is finely returning the ms part.

However matplotlib’s locator rules can’t handle microsecond or millisecond resolution. There aren’t any locators for less than second resolution.

Also, imshow sets the aspect of the plot to 1 by default, which is probably why you’re having to set the extents manually. If you specify “aspect=‘auto’” in the imshow call you can avoid that step. (However, strange things happen when the span of the extents drops below 100 microseconds… I’m guessing something is being cast to float32’s somewhere?)

plt.imshow(z.T, interpolation=‘nearest’, aspect=‘auto’, origin=‘lower’, extent=[xmin, xmax, 0, z.shape[1]])

I need to set both aspect and extent for my case, without the extend I can’t get the time axis placed.

As a quick example to demonstrate using sub-second resolution (without a proper tick locator):

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates

from datetime import datetime

Generate data…

ny = 100

nx = 100
xmin, xmax = mdates.date2num([datetime(2011, 01, 01, microsecond=1),
datetime(2011, 01, 01, microsecond=nx)])
data = np.random.random((ny, nx)) - 0.5

data = data.cumsum(axis=1)

Plot…

fig, ax = plt.subplots()

ax.imshow(data, aspect=‘auto’, extent=[xmin, xmax, 0, ny])
ax.xaxis_date()

plt.show()

At any rate, you can write a quick-and-dirty millisecond locator… Give me a bit and I’ll cobble one together. (It’s turning out to be slightly more complex than I thought…)

I am fine seeing the ticks at second resolution. It might be overkill for my plots to place millisecond ticks. It takes a while to render these ticks.

···

On Thu, Nov 10, 2011 at 11:14 AM, Joe Kington <jkington@…150…> wrote:

On Thu, Nov 10, 2011 at 10:06 AM, Gökhan Sever <gokhansever@…287…> wrote:

Thanks Joe,

I forgot to convert my numeric time array into a form that mpl can understand.

I198 time

O198

array([ 32643.78595805, 32643.82032609, 32643.85445309, …,

32871.46535802, 32871.49946594, 32871.53384495])

I199 ncnt

O199

array([0001-01-01 09:04:03+00:00, 0001-01-01 09:04:03+00:00,

0001-01-01 09:04:03+00:00, …, 0001-01-01 09:07:51+00:00,

0001-01-01 09:07:51+00:00, 0001-01-01 09:07:51+00:00], dtype=object)

Although, this doesn’t give me millisecond precision. Is there any way to get ms precision via datetime module?

This is not a matter for plotting, since second precision is good enough for eyes.

Then setting extent properly and either calling ax.xaxis_date or calling setters manually

I196 xmin = mdates.date2num(ncnt[0])

I197 xmax = mdates.date2num(ncnt[-1])

plt.imshow(z.T, interpolation=‘nearest’, aspect=‘auto’, origin=‘lower’, extent=[xmin, xmax, 0, z.shape[1]])

ax = plt.gca()

ax.xaxis.set_major_formatter(DateFormatter(‘%H:%M:%S’))

ax.xaxis.set_major_locator(SecondLocator(interval=30))

ax.xaxis.set_minor_locator(SecondLocator(interval=5))

gives me better control over the major/minor ticks.

On Thu, Nov 10, 2011 at 8:15 AM, Joe Kington <jkington@…150…> wrote:

On Wed, Nov 9, 2011 at 11:45 PM, Gökhan Sever <gokhansever@…287…> wrote:

Hello,

Is there any easy way to specify a time-axis using imshow to plot 2D data?

Sure, just call “ax.xaxis_date()” (or “yaxis_date”, depending on which axis you want to represent a date).

As a quick example:

import matplotlib.pyplot as plt

import matplotlib.dates as mdates
import numpy as np

Generate data…

ny = 100
xmin, xmax = mdates.datestr2num([‘01/01/2011’, ‘11/10/2011’])
data = np.random.random((ny, int(xmax-xmin)+1)) - 0.5

data = data.cumsum(axis=1)

Plot…

fig, ax = plt.subplots()
ax.imshow(data, extent=[xmin, xmax, 0, ny])
ax.xaxis_date()
fig.autofmt_xdate()

plt.show()

Cheers,

-Joe


RSA(R) Conference 2012

Save $700 by Nov 18

Register now

http://p.sf.net/sfu/rsa-sfdev2dev1


Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users


Gökhan


Gökhan