Skip to content
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

AttributeError: 'NoneType' object has no attribute 'offset' in SimpleTZ #209

Open
reteptilian opened this issue Aug 29, 2020 · 1 comment

Comments

@reteptilian
Copy link

I ran into this error trying to plot points with matplotlib (see code below to repro).

I worked around it by modifyingSimpleTZ.__eq__ to do an isinstance check:

    def __eq__(self, other: Any) -> bool:
        if not isinstance(other, SimpleTZ):
            return NotImplemented
        return self.offset == other.offset # type: ignore

Here is code to repro. This is with python 3.8.3, gpxpy 1.4.2 and matplotlib 3.2.2.

import gpxpy
import matplotlib.pyplot as plt

gpx_file = """<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.0" creator="GPSBabel - http://www.gpsbabel.org"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://www.topografix.com/GPX/1/0" xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
  <time>2010-08-06T10:36:35Z</time>
  <bounds minlat="45.735199945" minlon="14.288633270" maxlat="45.795349991" maxlon="14.377516648"/>
  <trk>
    <name>ACTIVE LOG #2</name>
    <number>1</number>
    <trkseg>
      <trkpt lat="45.772175035" lon="14.357659249">
        <ele>542.320923</ele>
        <time>2010-08-05T14:23:59Z</time>
      </trkpt>
    </trkseg>
  </trk>
</gpx>
"""
gpx = gpxpy.parse(gpx_file)

point = gpx.tracks[0].segments[0].points[0]
plt.plot(point.time, point.longitude)

Stack trace:

Traceback (most recent call last):
  File "c:/Users/pkesb/test.py", line 25, in <module>
    plt.plot(point.time, point.longitude)
  File "C:\Users\pkesb\anaconda3\lib\site-packages\matplotlib\pyplot.py", line 2761, in plot
    return gca().plot(
  File "C:\Users\pkesb\anaconda3\lib\site-packages\matplotlib\axes\_axes.py", line 1647, in plot
    lines = [*self._get_lines(*args, data=data, **kwargs)]
  File "C:\Users\pkesb\anaconda3\lib\site-packages\matplotlib\axes\_base.py", line 216, in __call__
    yield from self._plot_args(this, kwargs)
  File "C:\Users\pkesb\anaconda3\lib\site-packages\matplotlib\axes\_base.py", line 337, in _plot_args
    self.axes.xaxis.update_units(x)
  File "C:\Users\pkesb\anaconda3\lib\site-packages\matplotlib\axis.py", line 1518, in update_units
    self.set_units(default)
  File "C:\Users\pkesb\anaconda3\lib\site-packages\matplotlib\axis.py", line 1587, in set_units
    if u == self.units:
  File "C:\Users\pkesb\anaconda3\lib\site-packages\gpxpy\gpxfield.py", line 75, in __eq__
    return self.offset == other.offset # type: ignore
AttributeError: 'NoneType' object has no attribute 'offset'
@ekspla
Copy link
Contributor

ekspla commented Mar 24, 2021

It seems to me, as a newcomer in gpxpy, there are problems related to SimpleTZ (such as issue #190). I am not sure what is the best way: mod of SimpleTZ to a fully functional one, use of built-in zoneinfo in python 3.9+ (which is backported to 3.6+), keep SimpleTZ as simple as possible, etc.

Another workaround without the mod of gpxpy is to replace tzinfo.

import gpxpy
import matplotlib.pyplot as plt
import datetime as mod_datetime

def replace_tzinfo(dt):
    return dt.replace(tzinfo=mod_datetime.timezone(dt.utcoffset()))

gpx = gpxpy.parse(gpx_file)

for track in gpx.tracks:
    for segment in track.segments:
        for point in segment.points:
            point.time = replace_tzinfo(point.time)

point = gpx.tracks[0].segments[0].points[0]
plt.plot(point.time, point.longitude)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants