"Exploding" 在地图上绘制饼图的楔形(Python,matplotlib)
"Exploding" wedges of pie chart when plotting them on a map (Python, matplotlib)
所以我使用 ax.scatter 成功地在地图上绘制了饼图作为标记,但我在处理饼图中的某些楔形 "exploding" 时遇到了问题。我似乎无法在我的代码中找到原因,也无法在网上找到任何解释。此代码基于示例 here ,一位同事也使用过该示例并生成了正常、统一的饼图。我们之间找不到问题,也没有发生错误。
代码:
import numpy as np
import math
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap, cm
australia_data = np.zeros((24,12))
colors = ['red','yellow','blue','mediumorchid']
#pie chart locations
xlon=[146.7,166,101.6,137.4,145.1,113.6,169.7,113.3,176.0,139.6,148.9,124.2,132.4,142.0,129.6,148.0,116.5,142.8,141.7,128.0,113.6,120.7,128.3,148.6]
ylat=[-42.2,-19.2,-0.5,-3.5,-34.4,-8.7,-45.1,-1.0,-38.6,-26.7,-29.1,-20.0,-14.4,-18.9,-31.3,-6.6,-23.8,-3.4,-7.5,-25.6,3.8,-3.1,-1.9,-23.2]
#function to draw pie charts on map
def draw_pie(ax,X=0, Y=0, size = 1500):
xy = []
start = 0.17
ratios=[1/12.]*12
for ratio in ratios:
x = [0] + np.cos(np.linspace(2*math.pi*start,2*math.pi*(start+ratio))).tolist() #30
y = [0] + np.sin(np.linspace(2*math.pi*start,2*math.pi*(start+ratio))).tolist() #30
xy1=(zip(x,y))
xy.append(xy1)
start -= ratio
piecolors = []
for lt in range(12):
c = australia_data[b,lt]-1
c=int(c)
piecolors.append(colors[c])
for i, xyi in enumerate(xy):
ax.scatter([X],[Y] , marker=(xyi,0), s=size, facecolor=piecolors[i],linewidth=0.5,alpha=.7)
australia_data[:,11] = 1
australia_data[:,4] = 3
australia_data[:,1] = 2
fig = plt.figure()
ax = fig.add_axes([.05,.01,.79,.95])
x1 = 90 #left
x2 = 180 #right
y1 = -50 #bottom
y2 = 10 #top
#Create the map
m = Basemap(resolution='l',projection='merc', llcrnrlat=y1,urcrnrlat=y2,llcrnrlon=x1,urcrnrlon=x2,lat_ts=0) #,lat_ts=(x1+x2)/2
m.drawcoastlines()
#plots pie charts:
for b in range(24):
X,Y=m(xlon[b],ylat[b])
draw_pie(ax,X, Y,size=400)
plt.savefig('australia_pies.png',dpi=400)
任何关于为什么会发生这种情况(以及如何解决它!)的想法将不胜感激!
编辑:这似乎是饼图中楔形数量的问题 - 将其减少到 6 会导致均匀的饼图,但 7+ 会导致一些楔形 "explode"。
看scatter piecharts example,你忘了根据从0到楔形弧度的最大距离调整饼图楔形的大小。这是必要的,因为标记在绘制之前对给定的路径进行了标准化,因此不同的楔形需要不同的大小才能在最终图中以相同的大小出现。
import numpy as np
import matplotlib.pyplot as plt
#function to draw pie charts on map
def draw_pie(ax,X=0, Y=0, size = 1500):
xy = []; s=[]
start = 0.0
ratios=[1/12.]*12
for ratio in ratios:
x = [0] + np.cos(np.linspace(2*np.pi*start,2*np.pi*(start+ratio))).tolist() #30
y = [0] + np.sin(np.linspace(2*np.pi*start,2*np.pi*(start+ratio))).tolist() #30
xy1 = np.column_stack([x, y])
s1 = np.abs(xy1).max()
xy.append(xy1)
s.append(s1)
start -= ratio
for xyi, si in zip(xy,s):
ax.scatter([X],[Y] , marker=(xyi,0), s=size*si**2, edgecolor="k")
fig, ax = plt.subplots()
X,Y=166,50
draw_pie(ax,X, Y,size=3000)
plt.show()
所以我使用 ax.scatter 成功地在地图上绘制了饼图作为标记,但我在处理饼图中的某些楔形 "exploding" 时遇到了问题。我似乎无法在我的代码中找到原因,也无法在网上找到任何解释。此代码基于示例 here ,一位同事也使用过该示例并生成了正常、统一的饼图。我们之间找不到问题,也没有发生错误。
代码:
import numpy as np
import math
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap, cm
australia_data = np.zeros((24,12))
colors = ['red','yellow','blue','mediumorchid']
#pie chart locations
xlon=[146.7,166,101.6,137.4,145.1,113.6,169.7,113.3,176.0,139.6,148.9,124.2,132.4,142.0,129.6,148.0,116.5,142.8,141.7,128.0,113.6,120.7,128.3,148.6]
ylat=[-42.2,-19.2,-0.5,-3.5,-34.4,-8.7,-45.1,-1.0,-38.6,-26.7,-29.1,-20.0,-14.4,-18.9,-31.3,-6.6,-23.8,-3.4,-7.5,-25.6,3.8,-3.1,-1.9,-23.2]
#function to draw pie charts on map
def draw_pie(ax,X=0, Y=0, size = 1500):
xy = []
start = 0.17
ratios=[1/12.]*12
for ratio in ratios:
x = [0] + np.cos(np.linspace(2*math.pi*start,2*math.pi*(start+ratio))).tolist() #30
y = [0] + np.sin(np.linspace(2*math.pi*start,2*math.pi*(start+ratio))).tolist() #30
xy1=(zip(x,y))
xy.append(xy1)
start -= ratio
piecolors = []
for lt in range(12):
c = australia_data[b,lt]-1
c=int(c)
piecolors.append(colors[c])
for i, xyi in enumerate(xy):
ax.scatter([X],[Y] , marker=(xyi,0), s=size, facecolor=piecolors[i],linewidth=0.5,alpha=.7)
australia_data[:,11] = 1
australia_data[:,4] = 3
australia_data[:,1] = 2
fig = plt.figure()
ax = fig.add_axes([.05,.01,.79,.95])
x1 = 90 #left
x2 = 180 #right
y1 = -50 #bottom
y2 = 10 #top
#Create the map
m = Basemap(resolution='l',projection='merc', llcrnrlat=y1,urcrnrlat=y2,llcrnrlon=x1,urcrnrlon=x2,lat_ts=0) #,lat_ts=(x1+x2)/2
m.drawcoastlines()
#plots pie charts:
for b in range(24):
X,Y=m(xlon[b],ylat[b])
draw_pie(ax,X, Y,size=400)
plt.savefig('australia_pies.png',dpi=400)
任何关于为什么会发生这种情况(以及如何解决它!)的想法将不胜感激! 编辑:这似乎是饼图中楔形数量的问题 - 将其减少到 6 会导致均匀的饼图,但 7+ 会导致一些楔形 "explode"。
看scatter piecharts example,你忘了根据从0到楔形弧度的最大距离调整饼图楔形的大小。这是必要的,因为标记在绘制之前对给定的路径进行了标准化,因此不同的楔形需要不同的大小才能在最终图中以相同的大小出现。
import numpy as np
import matplotlib.pyplot as plt
#function to draw pie charts on map
def draw_pie(ax,X=0, Y=0, size = 1500):
xy = []; s=[]
start = 0.0
ratios=[1/12.]*12
for ratio in ratios:
x = [0] + np.cos(np.linspace(2*np.pi*start,2*np.pi*(start+ratio))).tolist() #30
y = [0] + np.sin(np.linspace(2*np.pi*start,2*np.pi*(start+ratio))).tolist() #30
xy1 = np.column_stack([x, y])
s1 = np.abs(xy1).max()
xy.append(xy1)
s.append(s1)
start -= ratio
for xyi, si in zip(xy,s):
ax.scatter([X],[Y] , marker=(xyi,0), s=size*si**2, edgecolor="k")
fig, ax = plt.subplots()
X,Y=166,50
draw_pie(ax,X, Y,size=3000)
plt.show()