开发者

Polar plot error bars don't rotate with angle in matplotlib

I want to create a polar bar plot with error bars in matplotlib. When I use the following code all my error bars have a horizontal alignment, and it looks wrong, unless the bar corresponds to the 90 or 270 degree case.

from numpy import *
from matplotlib import pyplot as py


r=zeros([16])
err=zeros([16]) 
for i in range(16):
    r[i]=random.randint(400,600)
    err[i]=random.randint(20,50)
theta=arange(开发者_StackOverflow中文版0,2*pi,2*pi/16)
width = pi*2/16

fig = py.figure(figsize=(8,8))
ax = fig.add_axes([0.1, 0.1, 0.75, 0.79], polar=True)

bars = ax.bar(theta+pi/16, r, width=width, bottom=0.0,yerr=err)
ax.set_ylim(0,700)
py.show()

Polar plot error bars don't rotate with angle in matplotlib

How to I get the error bars to take the theta of the individual bar into account?


So, it appears that the error bars are created with a Line2D object; that is, a dashed line is plotted with data points corresponding to the error bar positions (x[i],y[i]+yerr[i]). The dashes in the line are always the same, because they are just symbols. This obviously does not work for the polar plot. So this error bar setup needs to be deleted and each error bar must be added individually, with a line having the correct orientation.

Here is a routine that does this:

from matplotlib.lines import Line2D
from math import acos,sqrt

def correct_errorbar(ax,barlen=50,errorline=1):
    """
    A routine to remove default y-error bars on a bar-based pie chart and 
    replace them  with custom error bars that rotate with the pie chart.
    ax -- the axes object that contains the polar coordinate bar chart
    barlen -- the perpendicular length of each error bar
    errorline -- the number of the Line2D object that represents the original
       horizontal error bars.

    barlen will depend on the magnitude of the "y" values, ie the radius. 
    This routine was tested with a plot consisting solely of bar chart, and 
    if other Line2D objects are added, either directly or through further
    plot commands, errorline many need to be adjusted from its default value. 
    """
    # get error bar positions
    x,y = ax.lines[errorline].get_data()
    # remove incorrect bars
    del ax.lines[errorline]
    # add new lines fixing bars
    for i in range(len(y)):
        r = sqrt(barlen*barlen/4+y[i]*y[i])
        dt = acos((y[i])/(r))
        newline = Line2D([x[i]-dt,x[i]+dt],[r,r],lw=barlen/100.)
        ax.add_line(newline)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜