x axis non-uniform labeling (KURT PETERS)

I’m including the code below to demonstrate the problem. The top should have simtimedata (0 through 28) labeling the points. As you can see, MATPLOTLIB just distributes those values evenly instead of assigning them properly.
Any ideas?

#!/usr/bin/env python
import numpy as np
from matplotlib import rc
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import re
from matplotlib.ticker import EngFormatter
xdat=np.arange(1,11)
simtimedata = np.array([0, 1, 5, 9, 13, 18, 21, 24, 25, 28])
idatanp = np.array([-1,0, 1, 2, 3, 2, 1, 0, -1, -2])
print idatanp.shape
print simtimedata.shape
print xdat.shape
fig = plt.figure()

ax1 = fig.add_subplot(211)
ax1.plot(xdat,idatanp)
ax2 = fig.add_subplot(212)
#ax1.plot(x1, x1,‘b–’)
ax3 = ax2.twiny()
ax2.plot(xdat, idatanp.real,‘k-o’)
ax3.plot(simtimedata, idatanp,‘k–’,alpha=0)
ax2.set_title(“time domain”)
ax2.grid(True)
plt.show()

···

I’m trying to find a glitch in an FPGA simulation. The data stored in a file is:
(simulation time, y)

In reality, if I plot that I get large gaps because the simulation time continues and data is only output periodically. In other words simulation time is not continuous. I’d like to view the data without the gaps, but with simulation time annotating the x-axis so I can determine where the glitch occurs.
I’ve tried a variety of things:
#ax1.plot(x1, x1,‘b–’)
#ax3 = ax2.twiny()
ax2.set_xticklabels(simtimedata, fontdict=None, minor=False, rotation = 45)
ax2.plot( idatanp.real,‘k–’,idatanp.imag,‘g.-’)
#ax2.plot(xdat, idatanp.real,‘k–’,xdat,idatanp.imag,‘g.-’)
#ax3.plot(simtimedata, idatanp.real,‘k–’,alpha=0)

but cannot get the axis to both show the data all together AND show where the glitch occurs. I thought the twiny might help to put another x axis up so I could plot the data first with the x axis incrementing based on when the data is read in, and then trying to place labels showing simulation time.

Does anyone have any ideas how I could do this?
Kurt

Kurt,

You need to show ax3's xticklabels somewhere. Like this:
import numpy as np
from matplotlib import rc
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import re
from matplotlib.ticker import EngFormatter
xdat=np.arange(1,11)
simtimedata = np.array([0, 1, 5, 9, 13, 18, 21, 24, 25, 28])
idatanp = np.array([-1,0, 1, 2, 3, 2, 1, 0, -1, -2])

fig = plt.figure()
ax1 = fig.add_subplot(211)
ax1.plot(xdat,idatanp)

ax2 = fig.add_subplot(212)
ax3 = ax2.twiny()

ax2.plot(xdat, idatanp.real,'k-o')
ax3.plot(simtimedata, idatanp,'k--',alpha=0)

# ---- show ax3's xticklabels
ax3.xaxis.tick_top()
ax2.set_title("time domain")
ax2.grid(True)
fig.tight_layout()

···

On Mon, Sep 30, 2013 at 1:43 PM, KURT PETERS <peterskurt@...1954...> wrote:

I'm including the code below to demonstrate the problem. The top should
have simtimedata (0 through 28) labeling the points. As you can see,
MATPLOTLIB just distributes those values evenly instead of assigning them
properly.
Any ideas?

#!/usr/bin/env python
import numpy as np
from matplotlib import rc
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import re
from matplotlib.ticker import EngFormatter
xdat=np.arange(1,11)
simtimedata = np.array([0, 1, 5, 9, 13, 18, 21, 24, 25, 28])
idatanp = np.array([-1,0, 1, 2, 3, 2, 1, 0, -1, -2])
print idatanp.shape
print simtimedata.shape
print xdat.shape
fig = plt.figure()

ax1 = fig.add_subplot(211)
ax1.plot(xdat,idatanp)
ax2 = fig.add_subplot(212)
#ax1.plot(x1, x1,'b--')
ax3 = ax2.twiny()
ax2.plot(xdat, idatanp.real,'k-o')
ax3.plot(simtimedata, idatanp,'k--',alpha=0)
ax2.set_title("time domain")
ax2.grid(True)
plt.show()

>
> I'm trying to find a glitch in an FPGA simulation. The data stored in a
file is:
> (simulation time, y)
>
> In reality, if I plot that I get large gaps because the simulation time
continues and data is only output periodically. In other words simulation
time is not continuous. I'd like to view the data without the gaps, but
with simulation time annotating the x-axis so I can determine where the
glitch occurs.
> I've tried a variety of things:
> #ax1.plot(x1, x1,'b--')
> #ax3 = ax2.twiny()
> ax2.set_xticklabels(simtimedata, fontdict=None, minor=False, rotation =
45)
> ax2.plot( idatanp.real,'k--',idatanp.imag,'g.-')
> #ax2.plot(xdat, idatanp.real,'k--',xdat,idatanp.imag,'g.-')
> #ax3.plot(simtimedata, idatanp.real,'k--',alpha=0)
>
> but cannot get the axis to both show the data all together AND show
where the glitch occurs. I thought the twiny might help to put another x
axis up so I could plot the data first with the x axis incrementing based
on when the data is read in, and then trying to place labels showing
simulation time.
>
> Does anyone have any ideas how I could do this?
> Kurt

That doesn’t seem to fix it. What I’m expecting is at the top, 28 should correspond to the value -2. Instead it puts a 30 there.
Kurt

···

Date: Mon, 30 Sep 2013 16:20:50 -0700
Subject: Re: [Matplotlib-users] x axis non-uniform labeling (KURT PETERS)
From: pmhobson@…287…
To: peterskurt@…1954…
CC: matplotlib-users@…1544…ceforge.net

On Mon, Sep 30, 2013 at 1:43 PM, KURT PETERS <peterskurt@…1954…> wrote:

I’m including the code below to demonstrate the problem. The top should have simtimedata (0 through 28) labeling the points. As you can see, MATPLOTLIB just distributes those values evenly instead of assigning them properly.

Any ideas?

#!/usr/bin/env python
import numpy as np
from matplotlib import rc
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import re
from matplotlib.ticker import EngFormatter

xdat=np.arange(1,11)
simtimedata = np.array([0, 1, 5, 9, 13, 18, 21, 24, 25, 28])
idatanp = np.array([-1,0, 1, 2, 3, 2, 1, 0, -1, -2])
print idatanp.shape
print simtimedata.shape
print xdat.shape
fig = plt.figure()

ax1 = fig.add_subplot(211)
ax1.plot(xdat,idatanp)
ax2 = fig.add_subplot(212)
#ax1.plot(x1, x1,‘b–’)
ax3 = ax2.twiny()
ax2.plot(xdat, idatanp.real,‘k-o’)
ax3.plot(simtimedata, idatanp,‘k–’,alpha=0)

ax2.set_title(“time domain”)
ax2.grid(True)
plt.show()

I’m trying to find a glitch in an FPGA simulation. The data stored in a file is:
(simulation time, y)

In reality, if I plot that I get large gaps because the simulation time continues and data is only output periodically. In other words simulation time is not continuous. I’d like to view the data without the gaps, but with simulation time annotating the x-axis so I can determine where the glitch occurs.

I’ve tried a variety of things:
#ax1.plot(x1, x1,‘b–’)
#ax3 = ax2.twiny()
ax2.set_xticklabels(simtimedata, fontdict=None, minor=False, rotation = 45)
ax2.plot( idatanp.real,‘k–’,idatanp.imag,‘g.-’)

#ax2.plot(xdat, idatanp.real,‘k–’,xdat,idatanp.imag,‘g.-’)
#ax3.plot(simtimedata, idatanp.real,‘k–’,alpha=0)

but cannot get the axis to both show the data all together AND show where the glitch occurs. I thought the twiny might help to put another x axis up so I could plot the data first with the x axis incrementing based on when the data is read in, and then trying to place labels showing simulation time.

Does anyone have any ideas how I could do this?
Kurt

Kurt,

You need to show ax3’s xticklabels somewhere. Like this:

import numpy as np

from matplotlib import rc

import matplotlib.pyplot as plt

import matplotlib.mlab as mlab

import re

from matplotlib.ticker import EngFormatter

xdat=np.arange(1,11)

simtimedata = np.array([0, 1, 5, 9, 13, 18, 21, 24, 25, 28])

idatanp = np.array([-1,0, 1, 2, 3, 2, 1, 0, -1, -2])

fig = plt.figure()

ax1 = fig.add_subplot(211)

ax1.plot(xdat,idatanp)

ax2 = fig.add_subplot(212)

ax3 = ax2.twiny()

ax2.plot(xdat, idatanp.real,‘k-o’)

ax3.plot(simtimedata, idatanp,‘k–’,alpha=0)

---- show ax3’s xticklabels

ax3.xaxis.tick_top()

ax2.set_title(“time domain”)

ax2.grid(True)

fig.tight_layout()

It's not really clear to me what you're trying to do. But the rounding of
the axes limits is an expected behavior of matplotlib. You can set them
manually if you like. Also, I think this achieves what you want and is much
simpler.

import numpy as np
import matplotlib.pyplot as plt

xdat=np.arange(1,11)
simtimedata = np.array([0, 1, 5, 9, 13, 18, 21, 24, 25, 28])
idatanp = np.array([-1,0, 1, 2, 3, 2, 1, 0, -1, -2])

fig, (ax1, ax2) = plt.subplots(nrows=2, sharey=True)

ax1.plot(xdat,idatanp)
ax2.plot(simtimedata, idatanp,'k--')
ax2.set_xlim([simtimedata.min(), simtimedata.max()])

fig.tight_layout()

···

On Mon, Sep 30, 2013 at 4:50 PM, KURT PETERS <peterskurt@...1954...> wrote:

That doesn't seem to fix it. What I'm expecting is at the top, 28 should
correspond to the value -2. Instead it puts a 30 there.
Kurt

It’s not really clear to me what you’re trying to do. But the rounding of the axes limits is an expected behavior of matplotlib. You can set them manually if you like. Also, I think this achieves what you want and is much simpler.
import numpy as np

import matplotlib.pyplot as plt

xdat=np.arange(1,11)

simtimedata = np.array([0, 1, 5, 9, 13, 18, 21, 24, 25, 28])

idatanp = np.array([-1,0, 1, 2, 3, 2, 1, 0, -1, -2])

fig, (ax1, ax2) = plt.subplots(nrows=2, sharey=True)

ax1.plot(xdat,idatanp)

ax2.plot(simtimedata, idatanp,‘k–’)

ax2.set_xlim([simtimedata.min(), simtimedata.max()])

REPLY:

···

============================================================

here’s what SHOULD be happening

0 1 5 9 13 18 21 24 25 28

3 | x

           x          x
      x                    x
  x                             x

-1|x__________________x____

1 2 3 4 5 6 7 8 9 10

How can I make that happen? Instead, MPL is autoranging the top axis. I don’t want that I just want the actual labels to occur up there.

Kurt

2013/10/1 KURT PETERS <peterskurt@...1954...>:

here's what SHOULD be happening

    > 0 1 5 9 13 18 21 24 25 28
3 | x
    > x x
    > x x
    > x x
-1|_x__________________x_____
       1 2 3 4 5 6 7 8 9 10

How can I make that happen? Instead, MPL is autoranging the top axis. I
don't want that I just want the actual labels to occur up there.

Then just set the ticks and the tick labels of the axis:

import numpy as np
import matplotlib.pyplot as plt
xdat=np.arange(1,11)
simtimedata = np.array([0, 1, 5, 9, 13, 18, 21, 24, 25, 28])
idatanp = np.array([-1,0, 1, 2, 3, 2, 1, 0, -1, -2])
ax1 = plt.subplot(111)
ax1.plot(xdat,idatanp)
ax2 = ax1.twiny()
ax2.set_xticks(range(len(xdat)))
ax2.set_xticklabels(simtimedata)
plt.show()

Goyo

Date: Tue, 1 Oct 2013 19:35:39 +0200
Subject: Re: [Matplotlib-users] x axis non-uniform labeling (KURT PETERS)
From: goyodiaz@…287…
To: peterskurt@…1954…
CC: pmhobson@…287…; matplotlib-users@lists.sourceforge.net

2013/10/1 KURT PETERS <peterskurt@…1954…>:

here’s what SHOULD be happening

0 1 5 9 13 18 21 24 25 28
3 | x
x x
x x
x x
-1|x__________________x____
1 2 3 4 5 6 7 8 9 10

How can I make that happen? Instead, MPL is autoranging the top axis. I
don’t want that I just want the actual labels to occur up there.

Then just set the ticks and the tick labels of the axis:

import numpy as np
import matplotlib.pyplot as plt
xdat=np.arange(1,11)
simtimedata = np.array([0, 1, 5, 9, 13, 18, 21, 24, 25, 28])
idatanp = np.array([-1,0, 1, 2, 3, 2, 1, 0, -1, -2])
ax1 = plt.subplot(111)
ax1.plot(xdat,idatanp)
ax2 = ax1.twiny()
ax2.set_xticks(range(len(xdat)))
ax2.set_xticklabels(simtimedata)
plt.show()

Goyo

Goyo,

Thanks, the code below seems to work. The problem is that with “REAL/actual” data, I have SO many data points that each point is now labeled and it takes forever to render. And when it does render, I cannot read the axis because there are too many there. Is there a way to judiciously have it only display a certain number of values? Such as every 100th value?

Kurt

xdat=np.arange(1,11)
simtimedata = np.array([0, 1, 5, 9, 13, 18, 21, 24, 25, 28])
idatanp = np.array([-1,0, 1, 2, 3, 2, 1, 0, -1, -2])
print idatanp.shape
print simtimedata.shape
print xdat.shape
fig = plt.figure()

ax1 = fig.add_subplot(211)
ax1.plot(xdat,idatanp)
ax1.grid(True)
ax2 = fig.add_subplot(212)
ax2.plot(xdat, idatanp.real,‘k-o’)
ax2.set_xticks(xdat)
ax2.set_xticklabels(simtimedata)
#ax2.set_title(“time domain”)
ax2.grid(True)
plt.show()

ax2.set_xticks(xdat[::100])
ax2.set_xticklabels(simtimedata[::100])

Cheers, Jody

···

On Oct 1, 2013, at 10:55 AM, KURT PETERS <peterskurt@…1954…> wrote:

Goyo,

Thanks, the code below seems to work. The problem is that with “REAL/actual” data, I have SO many data points that each point is now labeled and it takes forever to render. And when it does render, I cannot read the axis because there are too many there. Is there a way to judiciously have it only display a certain number of values? Such as every 100th value?

Kurt

ax2.set_xticks(xdat)
ax2.set_xticklabels(simtimedata)

Jody Klymak

http://web.uvic.ca/~jklymak/

I thought that, too, but then he used the word 'judiciously'. I think that you want to change the xaxis major formatter so that it returns the indexed element of simtimedata as the label. Example to come in a moment.
-Sterling

···

On Oct 1, 2013, at 11:01AM, Jody Klymak wrote:

On Oct 1, 2013, at 10:55 AM, KURT PETERS <peterskurt@...1954...> wrote:

Goyo,
  Thanks, the code below seems to work. The problem is that with "REAL/actual" data, I have SO many data points that each point is now labeled and it takes forever to render. And when it does render, I cannot read the axis because there are too many there. Is there a way to judiciously have it only display a certain number of values? Such as every 100th value?
Kurt

ax2.set_xticks(xdat)
ax2.set_xticklabels(simtimedata)

ax2.set_xticks(xdat[::100])
ax2.set_xticklabels(simtimedata[::100])

Cheers, Jody

The philosophy of matplotlib is to have smart defaults, but always allow
the user to override. Perhaps you are looking for a particular "ticker"?

http://matplotlib.org/api/ticker_api.html

I hope this helps!
Ben Root

···

On Tue, Oct 1, 2013 at 1:55 PM, KURT PETERS <peterskurt@...1954...> wrote:

> Date: Tue, 1 Oct 2013 19:35:39 +0200

> Subject: Re: [Matplotlib-users] x axis non-uniform labeling (KURT PETERS)
> From: goyodiaz@...287...
> To: peterskurt@...1954...
> CC: pmhobson@...287...; matplotlib-users@lists.sourceforge.net

>
> 2013/10/1 KURT PETERS <peterskurt@...1954...>:
> > here's what SHOULD be happening
> >
> > > 0 1 5 9 13 18 21 24 25 28
> > 3 | x
> > > x x
> > > x x
> > > x x
> > -1|_x__________________x_____
> > 1 2 3 4 5 6 7 8 9 10
> >
> > How can I make that happen? Instead, MPL is autoranging the top axis. I
> > don't want that I just want the actual labels to occur up there.
>
> Then just set the ticks and the tick labels of the axis:
>
> import numpy as np
> import matplotlib.pyplot as plt
> xdat=np.arange(1,11)
> simtimedata = np.array([0, 1, 5, 9, 13, 18, 21, 24, 25, 28])
> idatanp = np.array([-1,0, 1, 2, 3, 2, 1, 0, -1, -2])
> ax1 = plt.subplot(111)
> ax1.plot(xdat,idatanp)
> ax2 = ax1.twiny()
> ax2.set_xticks(range(len(xdat)))
> ax2.set_xticklabels(simtimedata)
> plt.show()
>
> Goyo

Goyo,
  Thanks, the code below seems to work. The problem is that with
"REAL/actual" data, I have SO many data points that each point is now
labeled and it takes forever to render. And when it does render, I cannot
read the axis because there are too many there. Is there a way to
judiciously have it only display a certain number of values? Such as every
100th value?
Kurt
xdat=np.arange(1,11)
simtimedata = np.array([0, 1, 5, 9, 13, 18, 21, 24, 25, 28])
idatanp = np.array([-1,0, 1, 2, 3, 2, 1, 0, -1, -2])
print idatanp.shape
print simtimedata.shape
print xdat.shape
fig = plt.figure()

ax1 = fig.add_subplot(211)
ax1.plot(xdat,idatanp)
ax1.grid(True)
ax2 = fig.add_subplot(212)
ax2.plot(xdat, idatanp.real,'k-o')
ax2.set_xticks(xdat)
ax2.set_xticklabels(simtimedata)
#ax2.set_title("time domain")
ax2.grid(True)
plt.show()

Kurt,

Here is a self-contained example of what I think you are asking for:

{{{
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import FuncFormatter, MaxNLocator

simtimedata = np.array([0, 1, 5, 9, 13, 18, 21, 24, 25, 28, 31, 32, 41, 55, 56, 57])
idatanp = np.array([-1,0, 1, 2, 3, 2, 1, 0, -1, -2, -3, -2, -1, 0, -1, -2])
xdat = range(len(simtimedata))
fig = plt.figure()

ax1 = fig.add_subplot(211)
ax1.plot(xdat,idatanp)
ax1.grid(True)
ax2 = fig.add_subplot(212)
ax2.plot(xdat, idatanp.real,'k-o')
def index_to_label(i,dummy):
    if i >= 0 and i < len(simtimedata):
        return str(simtimedata[i])
    else:
        return ''

form = FuncFormatter(index_to_label)
ax2.xaxis.set_major_formatter(form)

#ax2.set_title("time domain")
ax2.grid(True)
plt.show()
}}}

You may also be interested in this question and answer on stackoverflow:

-Sterling

···

On Oct 1, 2013, at 8:59AM, KURT PETERS wrote:

REPLY:

here's what SHOULD be happening

    > 0 1 5 9 13 18 21 24 25 28
3 | x
    > x x
    > x x
    > x x
-1|_x__________________x_____
       1 2 3 4 5 6 7 8 9 10

How can I make that happen? Instead, MPL is autoranging the top axis. I don't want that I just want the actual labels to occur up there.

Kurt

Subject: Re: [Matplotlib-users] x axis non-uniform labeling (KURT PETERS)
From: smithsp@…4455…4…
Date: Tue, 1 Oct 2013 11:34:39 -0700
CC: pmhobson@…2015…87…; matplotlib-users@lists.sourceforge.net
To: peterskurt@…2823…4…

REPLY:

here’s what SHOULD be happening

0 1 5 9 13 18 21 24 25 28
3 | x
x x
x x
x x
-1|x__________________x____
1 2 3 4 5 6 7 8 9 10

How can I make that happen? Instead, MPL is autoranging the top axis. I don’t want that I just want the actual labels to occur up there.

Kurt

Kurt,

Here is a self-contained example of what I think you are asking for:

{{{
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import FuncFormatter, MaxNLocator

simtimedata = np.array([0, 1, 5, 9, 13, 18, 21, 24, 25, 28, 31, 32, 41, 55, 56, 57])
idatanp = np.array([-1,0, 1, 2, 3, 2, 1, 0, -1, -2, -3, -2, -1, 0, -1, -2])
xdat = range(len(simtimedata))
fig = plt.figure()

ax1 = fig.add_subplot(211)
ax1.plot(xdat,idatanp)
ax1.grid(True)
ax2 = fig.add_subplot(212)
ax2.plot(xdat, idatanp.real,‘k-o’)
def index_to_label(i,dummy):
if i >= 0 and i < len(simtimedata):
return str(simtimedata[i])
else:
return ‘’

form = FuncFormatter(index_to_label)
ax2.xaxis.set_major_formatter(form)

#ax2.set_title(“time domain”)
ax2.grid(True)
plt.show()
}}}

You may also be interested in this question and answer on stackoverflow:
python - How do I plot multiple X or Y axes? - Stack Overflow

-Sterling

Thanks Sterling,
That’s exactly what I was looking for. I ended up creating a class because I wasn’t comfortable using either a lambda function or simtimedata as a global variable (just a style issue). In case someone’s been following along and wants the final code:

from matplotlib.ticker import Formatter
class MyFormatter(Formatter):
def init(self, simtime):
self.simtime = simtime
def call(self,val,pos=0):
if val >= 0 and val < len(self.simtime):
return str(self.simtime[val])
else:
return ‘’
xdat=np.arange(0,10)
simtimedata = np.array([ 0, 1, 5, 9, 13, 18, 21, 24, 25, 28])
idatanp = np.array ([-1,0, 1, 2, 3, 2, 1, 0, -1, -2])
print idatanp.shape
print simtimedata.shape
print xdat.shape
fig = plt.figure()
intformatter = MyFormatter(simtimedata)
ax1 = fig.add_subplot(211)
ax1.plot(xdat,idatanp)
ax1.grid(True)
ax2 = fig.add_subplot(212)
ax2.plot(xdat, idatanp.real,‘k-o’)
ax2.xaxis.set_major_formatter(intformatter)
ax2.set_title(“time domain”)
ax2.grid(True)
plt.show()

···

On Oct 1, 2013, at 8:59AM, KURT PETERS wrote: