2

Is there a way to anchor the ticks and tick labels of the x-axis so that they cross the y-axis at a different location than where the actual x-axis crosses the y-axis? This can basically be accomplished with:

ax = plt.gca()
ax.get_xaxis().set_tick_params(pad=5)

or

ax.xaxis.set_tick_params(pad=500)

For example:

Waveform with x-axis anchored at y-axis 0 and tick labels anchored at y-axis -0.04223

Except that I am working with audio file inputs and the y-axis is variable (based on the highest/lowest amplitude of the waveform). Therefore, the maximum and minimum y-axis values change depending on the audio file. I am concerned that pad=NUM will be moving around relative to the y-axis.

Therefore, I am looking for a way to accomplish what pad does, but have the ticks and tick labels be anchored at the minimum y-axis value.

As a bonus, flipping this around so that the y-axis is anchored somewhere differently than the y-axis tick labels would surely benefit someone also.

In my particular case, I have the x-axis crossing the y-axis at y=0. The x-axis ticks and tick labels will sometimes be at -1.0, sometimes at -0.5, sometimes at -0.25, etc. I always know what the minimum value of the y-axis is, and therefore want it to be the anchor point for x-axis ticks and tick labels. (In fact, I am happy to do it with only the x-axis tick labels, if it is possible to treat ticks and tick labels separately). An example of this is shown in this image above (which I accomplished with pad=500).

I looked around other threads and in the documentation, but I'm either missing it or don't know the correct terms to find it.

David Z
  • 128,184
  • 27
  • 255
  • 279
whatisit
  • 219
  • 3
  • 12
  • Additionally, I found that including the waveform in a subplot requires the padding to be changed. So being able to get away from `pad` and anchor it to a value on the y-axis is preferred in this method also. – whatisit Jan 04 '17 at 07:43

2 Answers2

0

UPDATE: I added gridlines and was getting very unexpected behavior (e.g. linestyle and linewidth didn't work as expected) due to the top x-axis being shifted. I realized yet a better way - keep the axes (turn off the splines) and simply plot a second line at (0, 0) to (max_time, 0).

ax.plot([0,times[-1]], [0,0], color='k') # Creates a 'false' x-axis at y=0
ax.spines['top'].set_color('none') # Position unchanged
ax.spines['bottom'].set_color('none') # Position unchanged


Figured it out! I was thinking about this the wrong way...

Problem: Moving the bottom x-axis to the center and padding the tick labels

Solution: Keep the bottom x-axis where it is (turn off the bottom spine) and move the top x-axis to the center (keep top spine, but turn off ticks and tick labels).

ax.spines['top'].set_position('center')
ax.spines['bottom'].set_color('none') # Position unchanged
ax.xaxis.set_tick_params(top='off')
whatisit
  • 219
  • 3
  • 12
  • This is a good solution, but it seems like a bit of a 'hack', and that `ax.xaxis.set_label_position('bottom')` should *just work* but it doesn't... – Colin Oct 10 '21 at 10:13