I am attempting to annotate a point on a seaborn plot. Without the annotation, everything works as I want.
It fails with matplotlib.units.ConversionError: Failed to convert value(s) to axis units: '2020-05-14'
My full reproduction data and code is below.
Example dataset:
User name;Files changed;Lines added;Lines deleted;Total lines (delta);Commit count;Repository;Date
Dev 1;8;57;37;20;2;ava;2020-05-12
Dev 2;3;75;84;-9;2;ava;2020-05-12
Dev 3;2;327;0;327;1;ava;2020-05-12
Dev 2;20;424;132;292;7;ava;2020-05-14
Dev 3;13;114;25;89;3;ava;2020-05-14
Dev 1;4;107;10;97;1;ava;2020-05-14
Dev 4;5;390;0;390;1;ava;2020-05-14
Dev 2;1;2;6;-4;1;ava;2020-05-17
Dev 3;2;13;1;12;1;ava;2020-05-17
Dev 3;4;16;12;4;3;ava;2020-05-18
Dev 5;4;89;51;38;1;ava;2020-05-18
Dev 1;5;65;37;28;1;ava;2020-05-18
Dev 2;11;152;46;106;3;ava;2020-05-19
Dev 4;4;25;15;10;2;ava;2020-05-19
Dev 1;7;1010;15;995;2;ava;2020-05-19
Dev 5;2;4;4;0;1;ava;2020-05-19
Dev 6;1;1;1;0;1;ava;2020-05-19
Dev 1;5;13;31;-18;3;ava;2020-05-20
Dev 6;11;744;850;-106;2;ava;2020-05-20
Code:
import pandas as pd
import numpy as np
import seaborn as sns
from matplotlib import pyplot as plt
STATSFILE = "stats_test.csv"
stats = pd.read_csv(STATSFILE, sep=";", parse_dates=['Date'], date_parser=lambda x: pd.to_datetime(x, format='%Y-%m-%d'))
stats['Files changed'] = stats['Files changed'].astype('float64')
stats['Lines added'] = stats['Lines added'].astype('float64')
stats['Day of year'] = stats['Date'].dt.dayofyear # Add column for day of year - used to overlay plots
stats['Lines removed'] = stats['Lines deleted'] * -1
print(stats.info())
plt.figure(figsize=(15, 7))
line_group = stats.groupby(['Date']).sum()
sns.lineplot(
x="Date",
y="Lines added",
color='green',
ci=None, # Don't plot the confident interval
data=line_group
).set_title('Lines Changed')
sns.lineplot(
x="Date",
y="Lines removed",
color='red',
ci=None, # Don't plot the confident interval
data=line_group
).set_title('Lines Changed')
# IF I DO NOT PUT THIS ANNOTATE, IT PLOTS AS EXPECTED, SANS ANNOTATION
plt.annotate("Value here", xy=('2020-05-14',50),
size=12,
ha='right',
va="center",
arrowprops=dict(arrowstyle="->", color='black', connectionstyle="angle3,angleA=0,angleB=-90"))
plt.savefig('plot.png')
The dataframe looks as expected
RangeIndex: 19 entries, 0 to 18
Data columns (total 10 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 User name 19 non-null object
1 Files changed 19 non-null float64
2 Lines added 19 non-null float64
3 Lines deleted 19 non-null int64
4 Total lines (delta) 19 non-null int64
5 Commit count 19 non-null int64
6 Repository 19 non-null object
7 Date 19 non-null datetime64[ns]
8 Day of year 19 non-null int64
9 Lines removed 19 non-null int64
dtypes: datetime64[ns](1), float64(2), int64(5), object(2)
memory usage: 1.6+ KB
This is the full error I'm getting
Traceback (most recent call last):
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/axis.py", line 1523, in convert_units
ret = self.converter.convert(x, self.units, self)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/dates.py", line 1896, in convert
return date2num(value)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/dates.py", line 425, in date2num
tzi = getattr(d[0], 'tzinfo', None)
IndexError: too many indices for array: array is 0-dimensional, but 1 were indexed
The above exception was the direct cause of the following exception:
Traceback (most recent call last): [19/1989]
File "repostats.py", line 71, in <module>
plt.savefig('lineschanged.png')
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/pyplot.py", line 859, in savefig
res = fig.savefig(*args, **kwargs)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/figure.py", line 2311, in savefig
self.canvas.print_figure(fname, **kwargs)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/backend_bases.py", line 2210, in print_figure
result = print_method(
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/backend_bases.py", line 1639, in wrapper
return func(*args, **kwargs)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/backends/backend_agg.py", line 509, in print_png
FigureCanvasAgg.draw(self)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/backends/backend_agg.py", line 407, in draw
self.figure.draw(self.renderer)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/artist.py", line 41, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/figure.py", line 1863, in draw
mimage._draw_list_compositing_images(
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/image.py", line 131, in _draw_list_compositing_images
a.draw(renderer)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/artist.py", line 41, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/cbook/deprecation.py", line 411, in wrapper
return func(*inner_args, **inner_kwargs)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/axes/_base.py", line 2747, in draw
mimage._draw_list_compositing_images(renderer, self, artists)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/image.py", line 131, in _draw_list_compositing_images
a.draw(renderer)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/artist.py", line 41, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/text.py", line 1890, in draw
if not self.get_visible() or not self._check_xy(renderer):
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/text.py", line 1485, in _check_xy
xy_pixel = self._get_position_xy(renderer)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/text.py", line 1478, in _get_position_xy
return self._get_xy(renderer, x, y, self.xycoords)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/text.py", line 1346, in _get_xy
x = float(self.convert_xunits(x))
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/artist.py", line 175, in convert_xunits
return ax.xaxis.convert_units(x)
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/axis.py", line 1525, in convert_units
raise munits.ConversionError('Failed to convert value(s) to axis '
matplotlib.units.ConversionError: Failed to convert value(s) to axis units: '2020-05-14'
Code that is failing:
plt.annotate("Value here", xy=('2020-05-14',50),
size=12,
ha='right',
va="center",
arrowprops=dict(arrowstyle="->", color='black', connectionstyle="angle3,angleA=0,angleB=-90"))
To answer the duplicate suggestion - no that does not solve the problem:
plt.annotate("Value here", xy=(mdates.date2num('2020-05-14'),50),
size=12,
ha='right',
va="center",
arrowprops=dict(arrowstyle="->", color='black', connectionstyle="angle3,angleA=0,angleB=-90"))
This throws:
Traceback (most recent call last):
File "repo_test.py", line 35, in <module>
xy=(mdates.date2num('2020-05-14'), 50),
File "/home/devuser/.virtualenvs/repostats/lib/python3.8/site-packages/matplotlib/dates.py", line 425, in date2num
tzi = getattr(d[0], 'tzinfo', None)
IndexError: too many indices for array: array is 0-dimensional, but 1 were indexed
What am I doing wrong with this .annotate
call to cause a ConversionError
?