You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Using a date x-axis that are being autoscaled outside the initial data range due to the added vline then the first (and only the first) data label gets no rotation.
Code for reproduction
importmatplotlib.pyplotaspltimportmatplotlib.datesasmdatesimportdatetimedates= [datetime.datetime(2022, 2, 21, 0, 0),
datetime.datetime(2022, 2, 22, 0, 0),
datetime.datetime(2022, 2, 27, 0, 0)]
data1= [5,8,12]
fig, ax=plt.subplots(1, 1, figsize=(20/2.54, 12/2.54))
plt.subplots_adjust(left=0.08, bottom=0.15, right=0.95)
plt.title("Date x-axis label angle bug")
b1=ax.bar(dates, data1, width=0.7)
# Setup the date x-axis in weeks marking start of each week startax.xaxis.set_major_locator(mdates.WeekdayLocator(byweekday=mdates.MO))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%a %b %d'))
# The same problem regardless the method to set the angle#for label in ax.get_xticklabels(which='major'):# label.set(rotation=30, horizontalalignment='right')plt.xticks(rotation=30, ha="right")
# Add a vline to force the auoscaling outside the data rangeplt.axvline(x=datetime.datetime(2022, 3, 15, 0, 0))
plt.show()
Actual outcome
As can be seen in the screenshot the Feb 28 label is not rotated.
Expected outcome
That the dates are rotated as in the following screenshot.
Note: As long as the initial dates for the available data extends past Feb 28 then the labels are correctly rotated
Additional information
This seems to occur if the autoscale range is forced outside the initial range (as required by the data) by the addition of annotations and/or vlines outside the original x-axis data span.
I actually realized there is a trivial workaround and that is to change the order of the adjustment of the labels and additional graph details. So instead of
it works since I assume that with the addition of the vline the xmax is adjusted and the full scale range is subjected to the rotation adjustment. So this seems highly likely (but not certain) to be some corner case involving date axis generation.
@jklymak I can work on this if this is still an issue. Just want to make sure i understand the problem correctly, if the xticks method is used before the axvline method, the date should still rotate as shown in the expected outcome. Is this correct?
is probably the cause. We may have more ticks allocated internally than are returned by get_xticklabels.
That said, we haven't specified the behavior of plt.ticks(**kwargs). Does it only apply to current tick labels (which I think is the cause of the present issue), or does it define a global state similar to plt.tick_params(). If the latter, we probably have to tap into the mechanics used in tick_params(). Note however that parameter names may differ and we'd have to make sure to accept exactly the Text properties.
This might be a bit tedious. Therefore, I could also see an argument for not allowing plt.ticks(**kwargs), and instead refer the user to tick_params().
Call fig.draw_without_rendering before rotating the ticks?
I have the same problem, with the second tick (also a date) being the only one which is not rotated. I am using : plt.setp(ax.get_xticklabels(), rotation=30, ha='right')
Activity
jklymak commentedon Feb 21, 2022
Are dates actually needed to trigger this?
johan162 commentedon Feb 21, 2022
I cannot be absolutely sure but I haven't been able to recreate it with plain text labels. For example
Works as expected.
I actually realized there is a trivial workaround and that is to change the order of the adjustment of the labels and additional graph details. So instead of
you swap to
it works since I assume that with the addition of the vline the xmax is adjusted and the full scale range is subjected to the rotation adjustment. So this seems highly likely (but not certain) to be some corner case involving date axis generation.
mylasem commentedon Apr 11, 2022
@jklymak I can work on this if this is still an issue. Just want to make sure i understand the problem correctly, if the xticks method is used before the axvline method, the date should still rotate as shown in the expected outcome. Is this correct?
tacaswell commentedon Apr 11, 2022
@mylasem Correct, independently of what plotting is done and in what order, all of the ticks should be rotated the same.
timhoffm commentedon Apr 12, 2022
matplotlib/lib/matplotlib/pyplot.py
Lines 1817 to 1819 in b36ef47
is probably the cause. We may have more ticks allocated internally than are returned by
get_xticklabels.That said, we haven't specified the behavior of
plt.ticks(**kwargs). Does it only apply to current tick labels (which I think is the cause of the present issue), or does it define a global state similar toplt.tick_params(). If the latter, we probably have to tap into the mechanics used intick_params(). Note however that parameter names may differ and we'd have to make sure to accept exactly the Text properties.This might be a bit tedious. Therefore, I could also see an argument for not allowing
plt.ticks(**kwargs), and instead refer the user totick_params().jklymak commentedon Apr 4, 2023
Call fig.draw_without_rendering before rotating the ticks?
scpsc commentedon Jan 17, 2024
I have the same problem, with the second tick (also a date) being the only one which is not rotated. I am using :
plt.setp(ax.get_xticklabels(), rotation=30, ha='right')And this workaround works for me, thanks!
timhoffm commentedon Dec 9, 2024
The recommended solution from 3.11 on will be the new tick rotations modes introduced in #28968, i.e. here
I'm closing this as there is a current workaround (
fig.draw_without_rendering()) and a better future tick styling usingtick_params.