这里有一个解决方案,它使用ax.annotate在每个条内绘制箭头。由于OP不太清楚箭头应该是什么样子,所以我把每个条分成矩形(在代码中我称它们为squares,但如果你确定了绘图的纵横比,它们就只是正方形),并为每个矩形绘制了一个中心箭头,其方向由用户提供的角度给出(这里是一个称为wind_direction)。在
在代码中,我将Axes的纵横比设置为x-和y-极限的纵横比,这使得Axes呈正方形,因此可以轻松绘制长度相同的箭头,而不受其方向的影响。如果不需要,可以注释掉相应的行。如果箭头的长度必须相同而不受限制,则必须计算图形的纵横比,例如请参见here如何进行此操作。在
我还用度数标注了每个条上的风向,以便检查箭头是否与给定的风向一致。在from matplotlib import pyplot as plt
import numpy as np
fig,ax = plt.subplots()
x = np.arange(12)
wind_strength = np.random.random(12)
wind_direction = np.linspace(0,2*np.pi,12, endpoint = False)
colors = ['green', 'yellow', 'blue', 'pink', 'orange']
bar_cols = [colors[i%len(colors)] for i,s in enumerate(wind_strength)]
bars = ax.bar(x,wind_strength, color=bar_cols)
##computing the aspect ratio of the plot ranges:
xlim = ax.get_xlim()
ylim = ax.get_ylim()
aspect = (xlim[1]-xlim[0])/(ylim[1]-ylim[0])
##comment out this line if you don't care about the arrows being the
##same length
ax.set_aspect(aspect)
##dividing each bar into 'squares' and plotting an arrow into each square
##with orientation given by wind direction
for bar,angle in zip(bars,wind_direction):
(x1,y1),(x2,y2) = bar.get_bbox().get_points()
w = x2-x1
h = w/aspect
x_mid = (x1+x2)/2
dx = np.sin(angle)*w
dy = np.cos(angle)*h
##the top and bottom of the current square:
y_bottom = y1
y_top = y_bottom+h
##draw at least one arrow (for very small bars)
first = True
while y_top < y2 or first:
y_mid = (y_top+y_bottom)/2
ax.annotate(
'',xytext=(x_mid-dx/2,y_mid-dy/2),
xy=(x_mid+dx/2,y_mid+dy/2),
arrowprops=dict(arrowstyle="->"),
)
##next square
y_bottom = y_top
y_top += h
##first arrow drawn:
first = False
##annotating the wind direction:
ax.text(x_mid, y2+0.05, '{}'.format(int(180*angle/np.pi)), ha = 'center')
plt.show()
最终结果如下:
希望这有帮助。在