1

I'm plotting camapign data on a timeline, where only the time (rather than the date) sent is relevant hance the column contains only time data (imported from a csv)

It displays the various line graphs (spaghetti plot) however, when I want to add the labels to the x axis, I receive

RuntimeError: Locator attempting to generate 4473217 ticks from 30282.0 to 76878.0: exceeds Locator.MAXTICKS

I have 140 rows of data for this test file, the times are between 9:05 and 20:55 and my code is supposed to get a tick for every 15 minutes.

python: 3.7.1.final.0 python-bits: 64 OS: Windows OS-release: 10

pandas: 0.23.4

matplotlib: 3.0.2

My actual code looks like:

import pandas
import matplotlib.pyplot as plt
import  matplotlib.dates as mdates
from datetime import datetime


file_name = r'''C:\\Users\\A_B_testing.csv''' 
df1 = pandas.read_csv(file_name, encoding='utf-8')

df_Campaign1 = df1[df1['DataSource ID'].str.contains('Campaign1')==True]
Campaign1_times = df_Campaign1['time sent'].tolist()
Campaign1_revenue = df_Campaign1['EstValue/sms'].tolist()
Campaign1_times = [datetime.strptime(slot,"%H:%M").time() for slot in Campaign1_times]

df_Campaign2 = df1[df1['DataSource ID'].str.contains('Campaign2')==True]
Campaign2_times = df_Campaign2['time sent'].tolist()
Campaign2_revenue = df_Campaign2['EstValue/sms'].tolist()
Campaign2_times = [datetime.strptime(slot,"%H:%M").time() for slot in Campaign2_times]

fig, ax = plt.subplots(1, 1, figsize=(16, 8))

xlocator = mdates.MinuteLocator(byminute=None, interval=15) # tick every 15 minutes
xformatter = mdates.DateFormatter('%H:%M')

ax.xaxis.set_major_locator(xlocator)
ax.xaxis.set_major_formatter(xformatter)
ax.minorticks_off()

plt.grid(True)

plt.plot(Campaign1_times, Campaign1_revenue, c = 'g', linewidth = 1)
plt.plot(Campaign2_times, Campaign2_revenue, c = 'y', linewidth = 2)

plt.show()

I tired to reduce the number of values to be plotted and it worked fine on a dummy set as follows:

from matplotlib import pyplot as plt
import  matplotlib.dates as mdates
from matplotlib.dates import HourLocator, MinuteLocator, DateFormatter
from datetime import datetime

fig, ax = plt.subplots(1, figsize=(16, 6))

xlocator = MinuteLocator(interval=15)
xformatter = DateFormatter('%H:%M')
ax.xaxis.set_major_locator(xlocator)
ax.xaxis.set_major_formatter(xformatter)
ax.minorticks_off()

plt.grid(True, )

xvalues = ['9:05', '10:35' ,'12:05' ,'12:35', '13:05']
xvalues = [datetime.strptime(slot,"%H:%M") for slot in xvalues]
yvalues = [2.2, 2.4, 1.7, 3, 2]
zvalues = [3.2, 1.4, 1.8, 2.7, 2.2]

plt.plot(xvalues, yvalues, c = 'g')
plt.plot(xvalues, zvalues, c = 'b')

plt.show()

So I think that issue is related to the way I'm declaring the ticks, tried to find a relevant post here on but none has solved my problem. Can anyone please point me to the right direction? Thanks in advance.

PB1899
  • 400
  • 4
  • 13
  • I think this may be a "duplicate" of [this question](https://stackoverflow.com/questions/42398264/matplotlib-xticks-every-15-minutes-starting-on-the-hour). To repeat the top answer there, you shouldn't use `interval` to specify the 15-min interval (as this dictates only which tick gets a label), but rather use `MinuteLocator(byminute=[0,15,30,45], interval = 1)` – Asmus Apr 14 '19 at 11:42
  • @Asmus it changes the tick on the dummy set but I receive the same error message when running it on the actual set. As the script works with a part of the data I assume it's somehow still related to the quantity of data to be plotted, or..? – PB1899 Apr 14 '19 at 15:27
  • It seems your code tries to create minutely ticks over more than hundread years, i.e. between 28th November 0083 and 27th june 0211. That is weird for sure, but one cannot find out why it does that without [mcve], i.e. self-contained, runnable code in the question. – ImportanceOfBeingErnest Apr 14 '19 at 17:30
  • Expanding on what @ImportanceOfBeingErnest said, could you tell us what the results of `df_Campaign2['time sent'].min()` and `df_Campaign2['time sent'].max()` are? – Asmus Apr 14 '19 at 17:40
  • 1
    It seems that the dummy set didn't use the .time() when converting the 'time sent' values, so it looked like the min in the dummy set = datetime.datetime(1900, 1, 1, 9, 5) whilst the min in the actual = datetime.time(9, 45). When removing the .time() function, it worked fine - I couldn't find though that it has this possible behaviour. I spent some time and got help how to remove the 1900,1,1 par from the datetime object and it seems to cause the issue actually? – PB1899 Apr 14 '19 at 21:05

1 Answers1

0

I had a similar issue which got fixed by using datetime objects instead of time objects in the x-axis.

Similarly, in the code of the question, using the full datetime instead of just the time should fix the issue.

replace:
[datetime.strptime(slot,"%H:%M").time() for slot in ...

by:
[datetime.strptime(slot,"<full date format>") for slot in

Helio Santos
  • 6,606
  • 3
  • 25
  • 31