2

following on from my question here: Force the Y axis to only use integers and the great assistance I got there I have another issue with drawing a nice graph.

I'm using the pyplot module to draw a 2nd axis with some reference points on the top of the graph, and I can't seem to get the bottom and top x axis to agree on where the purportedly same location is...

Current output from the graph maker...

If you look on the graph, you'll see the marker for 1 Kb (the dotted line) and the 2nd axis ticker label for the same do not agree. Same with the 1 Mb, but the 1Gb seems to line up.

The 2nd axis comes from an overlaid subplot (as I understand it) kicked off here:

fig = plt.figure()
ax1 = fig.add_subplot(111)

I am using the same constraints for both the axis:

 ax1.set_xscale("log", basex=2)
 ax1.set_xlim(0,34359738368)  

and:

ax2 = ax1.twiny()
ax2.set_xlim(0,34359738368)
ax2.set_xscale("log", basex=2)

and the same values for the two sets of marks:

ax1.axvline(x=1024, color='black', linestyle='--')
ax1.axvline(x=1048576, color='black', linestyle='--')
ax1.axvline(x=1073741824, color='black', linestyle='--')

and:

ax2.set_xticks([1024, 1048576, 1073741824])
ax2.set_xticklabels(['1 Kbyte','1 Mbyte','1 Gbyte'], fontsize=8)

Any ideas why they aren't lining up? I'm sure I've done something dumb along the way..

Community
  • 1
  • 1
Jay Gattuso
  • 3,890
  • 12
  • 37
  • 51

1 Answers1

1

When I run exactly the snippets that you've posted, I get a graph which shows the disagreement you see, but also disagrees about what the x limits are:

In [68]: ax1.get_xlim()
Out[68]: (9.9999999999999995e-08, 34359738368.0)

In [69]: ax2.get_xlim()
Out[69]: (0.0, 34359738368.0)

This is (apparently) because you call set_xscale() and set_xlim() in different orders for the different axes, and log(0) gives -inf. If you have 0 as a boundary and then set a log axis it tries to recover from it, apparently, but not the other way around.

If you used 0 but used the same order:

In [103]: ax1.get_xlim()
Out[103]: (0.0, 34359738368.0)

In [104]: ax2.get_xlim()
Out[104]: (0.0, 34359738368.0)

or if you use a lower limit of 1 instead, you'd see:

In [88]: ax1.get_xlim()
Out[88]: (1.0, 34359738368.0)

In [89]: ax2.get_xlim()
Out[89]: (1.0, 34359738368.0)

Myself, I'd use the second approach: more explicit, and doesn't introduce an order dependence.

DSM
  • 342,061
  • 65
  • 592
  • 494