LokiTechnologies / EqualAreaCartogram

Converts a Shapefile, GeoJSON, or CSV to an equal area cartogram
MIT License
77 stars 10 forks source link

Errors when running in Python3 #9

Closed psychemedia closed 6 years ago

psychemedia commented 6 years ago

Trying to run the package using Python3 gives errors.

First error:

cart = Cartogram("sample_data/gujarat.json", #input filepath
                 id_col="AC_NO", num_x_grid=50, num_y_grid=40)
cart.make_hex_svg("sample_output/gujarat_sparse.svg", show=True)

AttributeError                            Traceback (most recent call last)
<ipython-input-6-dc59312a17f9> in <module>()
      1 cart = Cartogram("sample_data/gujarat.json", #input filepath
      2                  id_col="AC_NO", num_x_grid=50, num_y_grid=40)
----> 3 cart.make_hex_svg("sample_output/gujarat_sparse.svg", show=True)

~/Downloads/EqualAreaCartogram-master/eqcart/eqcart.py in make_hex_svg(self, output_fname, show, draw_text)
    195         """
    196         self._initialize_grid()
--> 197         self._populate_new_grid()
    198         cg = Chorogrid(self.df, self.df[self.index_col].tolist(), ['#eeeeee'] * len(self.df), id_column=self.index_col)
    199         cg.draw_hex(draw_text=draw_text)

~/Downloads/EqualAreaCartogram-master/eqcart/eqcart.py in _populate_new_grid(self)
    175             self.y_coords_points[self.point_position[point]['y_bin']].append(point)
    176 
--> 177         for point, value in self.point_position.iteritems():
    178             if (str(value["x_bin"]) + "_" + str(value["y_bin"])) not in self.coord_points:
    179                 self.coord_points[str(value["x_bin"]) + "_" + str(value["y_bin"])] = []

AttributeError: 'dict' object has no attribute 'iteritems'

In Python3, dict.iteritems has been replaced by dict.items.

rishsriv commented 6 years ago

Thanks for reporting this! Fix coming in 15 minutes.

rishsriv commented 6 years ago

Just fixed this. Thanks again for reporting - much appreciated.

psychemedia commented 6 years ago

Okay, still an issue:

cart = Cartogram("sample_data/gujarat.json", #input filepath
                 id_col="AC_NO", 
                 num_x_grid=25, num_y_grid=20 #reduced grid width and height to make map more dense
                )
cart.make_hex_geojson("sample_output/gujarat_dense.geojson")

TypeError                                 Traceback (most recent call last)
<ipython-input-8-09891a85aabf> in <module>()
      3                  num_x_grid=25, num_y_grid=20 #reduced grid width and height to make map more dense
      4                 )
----> 5 cart.make_hex_geojson("sample_output/gujarat_dense.geojson")

~/Documents/code/github forks/EqualAreaCartogram/eqcart/eqcart.py in make_hex_geojson(self, output_fname)
    229         geojson_dict = {"type": "FeatureCollection", "features": features}
    230         with open(output_fname, "wb") as f:
--> 231             json.dump(geojson_dict, f)

/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py in dump(obj, fp, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
    178     # a debuggability cost
    179     for chunk in iterable:
--> 180         fp.write(chunk)
    181 
    182 

TypeError: a bytes-like object is required, not 'str'

Drop the b?

rishsriv commented 6 years ago

Fixed, thanks

psychemedia commented 6 years ago

That gives me an error now (sorry, in my testing, I think I got messed up on the version I was running). I think that with the bytes dropped, line 87 in chorogrid/chorogrid.py now needs to remove the utf-8 coding?

f.write(svgstring.encode("utf-8")) -> f.write(svgstring)

I haven't tested with lots of encoded chars (unless your demo files contain them) so I don't know if this is robust. Encodings always catch me out:-(

rishsriv commented 6 years ago

Thanks again for reporting. Fixed it by handling the write function differently for py2 and py3.

if sys.version_info[0] >= 3:
    with open(save_filename, 'w', encoding='utf-8') as f:
        f.write(svgstring)
else:
    with open(save_filename, 'w') as f:
        f.write(svgstring.encode('utf-8'))

Should have done this much earlier. Will also write unit tests for both py2 and 3 so that errors like this do not go unnoticed.