简体   繁体   中英

Annotating seaborn lineplot fails with matplotlib.units.ConversionError: Failed to convert value(s) to axis units: '2020-05-14'

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"))

Graph (without annotations): 工作图 - 如果不包括注释

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 ?

The annotation does not take datetime values directly, therefore, it should be converted using mdates.dates2num .

xy=(mdates.date2num(datetime.datetime(2020,05,14)), 50)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM