'Why does Marker does not accept zipped objects in Matplotlib and how to correct it?
I'm trying to run the code shown below (which I obtained from this source) to introduce pie charts in a Baseman object.
import math
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
colors = ['red','blue','green','yellow','magenta','purple']
def draw_pie(ax,ratios=[0.4,0.3,0.3], X=0, Y=0, size = 1000):
N = len(ratios)
xy = []
start = 0.
for ratio in ratios:
x = [0] + np.cos(np.linspace(2*math.pi*start,2*math.pi*(start+ratio), 30)).tolist()
y = [0] + np.sin(np.linspace(2*math.pi*start,2*math.pi*(start+ratio), 30)).tolist()
xy1 = zip(x,y)
xy.append(xy1)
start += ratio
for i, xyi in enumerate(xy):
ax.scatter([X],[Y] , marker=(xyi,0), s=size, facecolor=colors[i] )
#ax.scatter([X],[Y] , marker=(2,0), s=size, facecolor=colors[i] )
fig = plt.figure(figsize=(11.7,8.3))
#Custom adjust of the subplots
plt.subplots_adjust(left=0.05,right=0.95,top=0.90,bottom=0.05,wspace=0.15,hspace=0.05)
ax = plt.subplot(111)
#Let's create a basemap around Belgium
m = Basemap(resolution='i',projection='merc', llcrnrlat=49.0,urcrnrlat=52.0,llcrnrlon=1.,urcrnrlon=8.0,lat_ts=51.0)
m.drawcountries(linewidth=0.5)
m.drawcoastlines(linewidth=0.5)
X,Y = m(4.5,50.5)
draw_pie(ax,[0.5,0.25,0.25], X, Y,size=300)
plt.savefig('test.png')
plt.savefig('test.pdf')
However, the code as provided produces the following error.
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-180-1520446b93e5> in <module>
27
28 X,Y = m(4.5,50.5)
---> 29 draw_pie(ax,[0.5,0.25,0.25], X, Y,size=300)
30 plt.savefig('test.png')
31 plt.savefig('test.pdf')
<ipython-input-180-1520446b93e5> in draw_pie(ax, ratios, X, Y, size)
15
16 for i, xyi in enumerate(xy):
---> 17 ax.scatter([X],[Y] , marker=(xyi,0), s=size, facecolor=colors[i] )
18
19 fig = plt.figure(figsize=(11.7,8.3))
~/opt/anaconda3/lib/python3.8/site-packages/matplotlib/__init__.py in inner(ax, data, *args, **kwargs)
1445 def inner(ax, *args, data=None, **kwargs):
1446 if data is None:
-> 1447 return func(ax, *map(sanitize_sequence, args), **kwargs)
1448
1449 bound = new_sig.bind(ax, *args, **kwargs)
~/opt/anaconda3/lib/python3.8/site-packages/matplotlib/cbook/deprecation.py in wrapper(*inner_args, **inner_kwargs)
409 else deprecation_addendum,
410 **kwargs)
--> 411 return func(*inner_args, **inner_kwargs)
412
413 return wrapper
~/opt/anaconda3/lib/python3.8/site-packages/matplotlib/axes/_axes.py in scatter(self, x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, verts, edgecolors, plotnonfinite, **kwargs)
4471 marker_obj = marker
4472 else:
-> 4473 marker_obj = mmarkers.MarkerStyle(marker)
4474
4475 path = marker_obj.get_path().transformed(
~/opt/anaconda3/lib/python3.8/site-packages/matplotlib/markers.py in __init__(self, marker, fillstyle)
226 self._marker_function = None
227 self.set_fillstyle(fillstyle)
--> 228 self.set_marker(marker)
229
230 def _recache(self):
~/opt/anaconda3/lib/python3.8/site-packages/matplotlib/markers.py in set_marker(self, marker)
311 if not isinstance(marker, MarkerStyle):
312 self._marker = marker
--> 313 self._recache()
314
315 def get_path(self):
~/opt/anaconda3/lib/python3.8/site-packages/matplotlib/markers.py in _recache(self)
239 self._capstyle = 'butt'
240 self._filled = True
--> 241 self._marker_function()
242
243 def __bool__(self):
~/opt/anaconda3/lib/python3.8/site-packages/matplotlib/markers.py in _set_tuple_marker(self)
370 symstyle = marker[1]
371 if symstyle == 0:
--> 372 self._path = Path.unit_regular_polygon(numsides)
373 self._joinstyle = 'miter'
374 elif symstyle == 1:
~/opt/anaconda3/lib/python3.8/site-packages/matplotlib/path.py in unit_regular_polygon(cls, numVertices)
711 centered at (0, 0).
712 """
--> 713 if numVertices <= 16:
714 path = cls._unit_regular_polygons.get(numVertices)
715 else:
TypeError: '<=' not supported between instances of 'zip' and 'int'
I was able to track down the problem to
ax.scatter([X],[Y] , marker=(xyi,0), s=size, facecolor=colors[i] )
xyi is the "shape" of a polygon that will emulate the pie piece in the pie chart, but this is not accepted by marker. If the xyi is replaced by a int (like in the commented line), the script will run with no errors, but of course, there will be no pie chart... Apparently, marker only accepts an integer in this position. Not a list or a zip (as it is the case now).
I have searched how this particular marker works, but cannot understand how it is intended to operate and therefore cannot correct the script to make it work. Is there a way to correct this error?
Solution 1:[1]
The source you provided was created in 2010. Matplotlib has changed a lot since then. Your draw_pie function can be replaced with this now:
def draw_pie(ax, ratios=[0.4, 0.3, 0.3], X=0, Y=0, size=1):
ax.pie(ratios,center=(X, Y), radius=size, frame=True)
Your code should work with:
fig = plt.figure(figsize=(11.7,8.3))
#Custom adjust of the subplots
plt.subplots_adjust(left=0.05,right=0.95,top=0.90,bottom=0.05,wspace=0.15,hspace=0.05)
ax = plt.subplot(111)
#Let's create a basemap around Belgium
m = Basemap(resolution='i',projection='merc', llcrnrlat=49.0,urcrnrlat=52.0,llcrnrlon=1.,urcrnrlon=8.0,lat_ts=51.0)
m.drawcountries(linewidth=0.5)
m.drawcoastlines(linewidth=0.5)
X,Y = m(4.5,50.5)
draw_pie(ax,[0.5,0.25,0.25], X, Y,size=3)
plt.savefig('test.png')
plt.savefig('test.pdf')
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
