Matplotlib Secondary x-Axis with different Labels & Ticks

Viewed 3926

I want to plot something with two x-axes. However the xticks don't align. Somehow the margins are ignored?! In the final version, the xlabels are different that means simply showing the axis at the top is not an option.

import matplotlib.pyplot as plt
import numpy as np 

fig = plt.figure(figsize=(10.0, 4.0))
axs = fig.subplots(2, 2)

xticklabels = [str(x) for x in range(0, 40+1, 5)]
y = np.random.rand(41*8)
ax0 = axs[0,0].twiny()
axs[0,0].set_xticks(np.arange(0,41*8,5*8))
axs[0,0].set_xticklabels(xticklabels)
ax0.set_xlim(axs[0,0].get_xlim())
ax0.set_xticks(np.arange(0,41*8,5*8))
ax0.set_xticklabels(xticklabels)

axs[0,0].plot(y)

plt.show()

enter image description here

EDIT: Actually I want to have something like this:

import matplotlib.pyplot as plt
import numpy as np 

fig = plt.figure(figsize=(10.0, 4.0))
axs = fig.subplots(2, 2)

xticklabels = [str(x) for x in range(0, 40+1, 5)]
y = np.random.rand(41*8)
ax0 = axs[0,0].twiny()
axs[0,0].set_xticks(np.arange(0,41*8,5*8))
axs[0,0].set_xticklabels(xticklabels)
ax0.set_xlim(axs[0,0].get_xlim())
ax0.set_xticks(np.arange(10*8,31*8,5*8))
ax0.set_xticklabels(["0", "25", "50", "75", "100"])

axs[0,0].plot(y)

plt.show()

enter image description here

But as you can see the ticks don't align. I'm getting crazy!

2 Answers

If you just want to show a second x-axis (without plotting anything on it) it may be easier with a scondary axis. You'll have to change the functions as needed:

import matplotlib.pyplot as plt
import numpy as np 

y = np.random.rand(41*8)

fig,ax = plt.subplots()
ax.set_xticks(np.arange(0,41*8,5*8))
xticklabels = [str(x) for x in range(0, 41, 5)]
ax.set_xticklabels(xticklabels)

secx = ax.secondary_xaxis('top', functions=(lambda x: x/8, lambda x: x/8))

ax.plot(y)
plt.show()

enter image description here


I assume that the problem with twiny is due to the absence of data on the new Axes, but I didn't manage to get it working, even after manually setting the data interval.


Update as per comment and edited question:

secx = ax.secondary_xaxis('top', functions=(lambda x: 5*x/8-50, lambda x: 5*x/8-50))
secx.set_xticks([0,25,50,75,100])
secx.set_xticklabels([f'{x}' for x in secx.get_xticks()])

enter image description here

Ok my workaround now was simply plotting the data with the second axis without color.

import matplotlib.pyplot as plt
import numpy as np 


fig,axs = plt.subplots()

xticklabels = [str(x) for x in range(0, 40+1, 5)]
y = np.random.rand(41*8)

axs.set_xticks(np.arange(0,41*8,5*8))
axs.set_xticklabels(xticklabels)
ax0 = axs.twiny()

ax0.set_xticks(np.arange(10*8,31*8,5*8))
ax0.set_xticklabels(["0", "25", "50", "75", "100"])
axs.plot(y)
ax0.plot(y, color ="None")

plt.show()
Related