New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Daylocator causes frozen computer when used with FuncAnimation #20202
Comments
There's not so much an issue with animations here, but an issue with #!/usr/bin/python3
import datetime
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
# np line space does not support datetime objects. Function to create a np line space.
# start, end are date_time objects
def date_linespace(start, end, steps):
delta = (end - start) / steps
increments = range(0, steps) * np.array([delta]*steps)
return start + increments
# use two sub plots
fig, ax = plt.subplots(figsize=(5, 4)) # size of graphic
# Major ticks every day
fmt_day = mdates.DayLocator(interval=1)
fmt_day.MAXTICKS = 40 # has NO effect
ax.xaxis.set_major_locator(fmt_day)
# create x time series data: start > end in n frames
# init frames. X- coordinates of type: numpy.ndarray
start_datetime_object = datetime.datetime(2019, 8, 8)
end_datetime_object = datetime.datetime(2019, 8, 23)
frames = date_linespace(start_datetime_object, end_datetime_object, 10)
fake_y_data = [2,1,0,1,1,3,0,1,2,3,2,3,0,3,3,1,2,0,2,1] # test data
# format line
line, = plt.plot([], [], '-r') # - = solid line, r = red. Must be iterable ","
line.set_data(frames, fake_y_data[:len(frames)])
# This works fine
#line, = plt.plot(frames, fake_y_data[:len(frames)], '-r')
plt.show() Plotting the data normally works fine, but it looks like |
Well, its even simpler: import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates
fig, ax = plt.subplots()
fmt_day = mdates.DayLocator(interval=1)
fmt_day.MAXTICKS = 40 # has NO effect
ax.xaxis_date()
ax.xaxis.set_major_locator(fmt_day)
plt.show() And this is just a consequence of 2000-2010 being the default axes limits for dates. To get around this, set your initial limits sensibly: import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates
fig, ax = plt.subplots()
fmt_day = mdates.DayLocator(interval=1)
fmt_day.MAXTICKS = 40 # has NO effect
ax.xaxis_date()
ax.xaxis.set_major_locator(fmt_day)
ax.set_xlim(np.datetime64('2019-01-01'), np.datetime64('2019-02-01'))
plt.show() I don't think there is anything we can do here. The default limit is the default limit, and since you have an empty axes, that is what you have to work with on the first draw. I would load the first draw with the first data point... |
@ jklymak Thank you for replying. Yes that worked!!! Great This is a big step for all who have similar issues. Let's describe correctly for future reference. The correct code is:
Thank you very much :-) |
Actually I'll re-open. The 2000-2010 comes from i.e. something like:
where the date limits are appropriate for the smaller locators in |
Can I give this a shot? |
Tinkering around with this, I found that the setting of default ticks happens in Would changing the default ticks over at |
fig, ax = plt.subplots()
fmt_day = mdates.DayLocator(interval=1)
ax.xaxis_date()
ax.xaxis.set_major_locator(fmt_day)
plt.show() I am not sure this patch works here, as @jeffreypaul15 mentioned, I was thinking however if it was possible to do some checking when user does Or, perhaps, we could make sure that
I tried to do something, but was not sure what the intended behavior was, and whether this is actually a bug. And also, my attempts were breaking current functionality 🤦, but thought at least I would describe what I found, but yeah I am not sure. Thoughts @tacaswell @jklymak? |
@jeffreypaul15 @dmatos2012 my apologies, this fell off my radar. I'm going to close this. yeah, its annoying, but the default limit is chosen at fig, ax = plt.subplots()
fmt_day = mdates.DayLocator(interval=1)
fmt_day.MAXTICKS = 40 # has NO effect
ax.xaxis_date()
ax.xaxis.set_major_locator(fmt_day)
ax.set_xlim(np.datetime64('2001-01-01'), np.datetime64('2001-01-10')) works fine. however, if anyone strongly objects or has a way forward, happy to re-open. |
I'm having the same/similar issue with matplotlib 3.5.2. Plotting hangs unless I add:
It seems that matplotlib wants to explicitly know the starting and end x limits. Whatever default value causes the code to hang. |
@ba05 The issue is that the default range is ~10 years (When we know nothing about the data we have to pick something). If you then set the locator to daily, we try to plot 3.65k ticks which is a very slow process (rendering text is expensive). |
I guess the argument could be made that the default range can be changed to 0-1 (days) like all other axes now that we have 1970 as the epoch. The historical problem with 0-1 was that with the old epoch it was an illegal date! The problem with changing it is that some folks may still use the old epoch, and back compatibility. |
Can a warning be added when taking an inordinate amount of time to execute? |
The problem is that it's running synchronously, so your options for issuing the warning are either before it runs, or after, the latter of which sounds kinda pointless. |
We used to have warnings when trying to draw a large number of ticks, but I think we removed them because they were annoying users who really did want that many ticks... |
Bug report
This is an existing bug that is already known but it might be prevented by using extra initialization steps.
I hope someone can guide me.
Error:
"Locator attempting to generate 4018 ticks ([10775.0, ..., 14792.0]), which exceeds Locator.MAXTICKS (40)."
Day locator is generating far too many day or hour ticks (thousands). This is causing to slow down the code to freeze for minutes or to completely freeze computer. I have seen Daylocator working properly so it may only happen in conjunction with FuncAnimation. My code must update the graph every few seconds. I use FuncAnimation wich an update function to do that.
I think the combination of both causes this issue. If I cannot solve it I must stop using Matplotlib. More people might be looking for it. That is the reason for posting.
Conditions and versions
Using OS Ubuntu 18.04
Python: 3.6.9
Matplotlib: 3.3.3
Matplotlib backend: Qt5Agg
The bug
The bug is explained in detail here:
runningcode11 and here stackoverflow
It is caused by missing initialization in rrulelocator. I tried to set this by running SecondLocator, MinuteLocation, HourLocator before. This is not working.
Code for reproduction
Actual outcome
Expected outcome
Proper initialization should avoid create all those ticks an memory corruption that is coming from it.
The text was updated successfully, but these errors were encountered: