Recently I posted this question about creating a border and controlling tick label locations. @ImportanceOfBeingErnest had a couple nice ways of controlling the border, but I was left with the tick label location issue.
I was able to track down the post I mentioned regarding using a transform to control tick label location padding (also explained by @ImportanceOfBeingErnest). I was able to implement this solution to change the tick label locations, but I have found an issue that I can't solve.
When the plot is initiated (using the desired tick label location) everything looks fine (see first fig below). But, as the data is updated (which is my application happens when a user adds a new data to a dataset), sometimes the tick label location remains properly places (i.e. with the specified padding), but sometimes it does not. Sometimes it is in the "default" (unpadded) location, sometimes it appears to be padded in the wrong direction, etc. It actually seems quite random. See additional figures below.
Below is a simple example of what I'm seeing in my full code. To keep it "minimal" I'm initializing a plot with no data and the first and last tick label adjust as desired, then updating a random set of points to the plot in a loop (4 times). As I mentioned, sometimes it's fine, sometimes it's not.
Any idea what is going on and how to address it to have the first and last tick label consistently padded inside the plot area so they don't get covered by the boarder?
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.transforms
def update_data(a):
X = np.random.randint(low=-9, high=9, size=10)
Y = np.random.randint(low=-9, high=9, size=10)
ax.set(xlim=[np.floor(np.min(X) - 1), np.ceil(np.max(X) + 1)], ylim=[np.floor(np.min(Y) - 1), np.ceil(np.max(Y) + 1)])
ax.scatter(X, Y, c="b", marker="o", s=40)
if __name__ == '__main__':
plt.ion()
fig, ax = plt.subplots()
ax2 = fig.add_subplot(111)
ax2.patch.set_visible(False)
ax2.tick_params(left=False, bottom=False, labelleft=False, labelbottom=False)
for _, sp in ax2.spines.items():
sp.set_linewidth(3)
ax.axis([-10, 10, -10, 10])
ax.spines['left'].set_position('zero')
ax.spines['bottom'].set_position('zero')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.setp(ax.xaxis.get_majorticklabels()[0], ha='left')
plt.setp(ax.xaxis.get_majorticklabels()[-1], ha='right')
plt.setp(ax.yaxis.get_majorticklabels()[0], va='bottom')
plt.setp(ax.yaxis.get_majorticklabels()[-1], va='top')
delx = 5 / 72.
dely = 5 / 72.
offsetX = matplotlib.transforms.ScaledTranslation(delx, 0, fig.dpi_scale_trans)
offsetY = matplotlib.transforms.ScaledTranslation(0, dely, fig.dpi_scale_trans)
ax.xaxis.get_majorticklabels()[0].set_transform(ax.xaxis.get_majorticklabels()[0].get_transform() + offsetX)
ax.xaxis.get_majorticklabels()[-1].set_transform(ax.xaxis.get_majorticklabels()[-1].get_transform() - offsetX)
ax.yaxis.get_majorticklabels()[0].set_transform(ax.yaxis.get_majorticklabels()[0].get_transform() + offsetY)
ax.yaxis.get_majorticklabels()[-1].set_transform(ax.yaxis.get_majorticklabels()[-1].get_transform() - offsetY)
ax.grid(True)
fig.set_tight_layout(True)
ax.scatter([], [], c="b", marker="o", s=40)
plt.show()
plt.pause(3)
for a in range(1, 4):
update_data(a)
plt.pause(3)
plt.draw()