我正在尝试使用matplotlib和python 2.7制作极坐标图,但是我在努力增加该同一轴的X轴和Tick标签之间的间距。如您在图片上看到的,12:00和6:00的标签看起来很好,我希望所有其他标签的空间都一样。

我尝试过

ax.xaxis.LABELPAD = 10

但这没有任何作用。

这是我的代码(对不起,一团糟。。。):
import numpy as np
import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.dates
from matplotlib.dates import YearLocator, MonthLocator, DateFormatter
import matplotlib.cm as cm
import matplotlib.ticker as tkr
import pdb
def plot_clock(data,filename,path,**kwargs): # (x,y,colors,lab_x,lab_y,xTicks,filename,legend,**kwargs):
    bins = [0,0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5,11.5,12,12.5,13.5,14.5,15.5,16.5,17.5,18.5,19.5,20.5,21.5,22.5,23.5,23.999999];
    data = np.array(data)/(60*60)
    DATA_ = np.histogram(data,bins)[0]
    def hour_formatAM(x, p):
        #pdb.set_trace()
        if x > 0:
            return str(format(x*6/np.pi, "01.0f") + ':00')
        else:
            return '12:00'

    def hour_formatPM(x, p):
        #pdb.set_trace()
        if x > 0:
            return str(format(x*6/np.pi+12, "01.0f") + ':00')
        else:
            return '24:00'

    '''font = {'family' : 'normal',
        'weight' : 'bold',
        'size'   : 12}
    mpl.rc('font', **font)'''

    mpl.rcParams.update({'font.size': 8})
    #sub plot AM
    theta = np.array(bins[1:13]) * np.pi / 6
    radii =  DATA_[1:13]
    radii[-1] += DATA_[0]
    width = 1 * np.pi / 6

    fig = plt.figure(figsize=(5.5,3),dpi=600)
    ax = fig.add_subplot(121, polar=True)
    bars = ax.bar(theta, radii, width=width, bottom=0)
    ax.set_theta_offset(np.pi/2)
    ax.set_theta_direction(-1)

    ax.xaxis.set_ticks(np.arange(0, np.pi*2, np.pi/6))
    ax.get_xaxis().set_major_formatter(tkr.FuncFormatter(hour_formatAM))
    ax.yaxis.set_ticks(np.arange(1,max(DATA_),1))
    for t, bar in zip(theta, bars):
        bar.set_facecolor(plt.cm.jet(t / 12.))
        bar.set_alpha(0.5)


    #sub plot PM
    theta = np.array(bins[14:26]) * np.pi / 6
    radii =  DATA_[14:26]
    radii[-1] += DATA_[13]
    width = 1 * np.pi / 6

    ax = fig.add_subplot(122, polar=True)
    bars = ax.bar(theta, radii, width=width, bottom=0)
    ax.set_theta_offset(np.pi/2)
    ax.set_theta_direction(-1)
    pdb.set_trace()
    ax.xaxis.set_ticks(np.arange(0, np.pi*2, np.pi/6))
    ax.get_xaxis().set_major_formatter(tkr.FuncFormatter(hour_formatPM))
    ax.yaxis.set_ticks(np.arange(1,max(DATA_),1))
    for t, bar in zip(theta, bars):
        bar.set_facecolor(plt.cm.jet(t / 12.))
        bar.set_alpha(0.5)
    #pdb.set_trace()
    #fig.tight_layout()
    #xlabels = [item.get_text() for item in ax.get_xticklabels()]
    ax.xaxis.LABELPAD = 10
    #[item.set_fontsize(12) for item in ax.xaxis.get_major_ticks()]

    fig.subplots_adjust(wspace = 0.4) # http://matplotlib.org/faq/howto_faq.html
    fig.savefig(path + filename,format='pdf')


data = [ 10.49531611,  22.49511583,  10.90891806,  18.99525417,
        21.57165972,   6.687755  ,   6.52137028,  15.86534639,
        18.53823556,   6.32563583,  12.99365833,  11.06817056,
        17.29261306,  15.31288556,  19.16236667,  10.38483333,
        14.51442222,  17.01413611,   6.96102278,  15.98508611,
        16.5287    ,  15.26533889,  20.83520278,  17.21952056,
         7.3225775 ,  16.42534361,  14.38649722,  21.63573111,  16.19249444]
data = np.array(data)*60*60
plot_clock(data,'figure2_StartTime.pdf','./')

最佳答案

@dabillox已经提到了使用frac kwarg到ax.set_thetagrids

但是,正如您所注意到的,您真正想要更改的是刻度标签的对齐方式,而不是刻度标签的整体径向位移。

附带一提,labelpad无效的原因是它控制轴标签(例如plt.xlabelplt.ylabel)和轴之间的填充,而不是刻度标签。

首先,您可以更加简洁地编写示例代码。这差不多是我将如何处理您正在做的事情(请注意,这与刻度标签的定位仍然存在相同的问题):

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as tkr

def main():
    data = [ 10.49531611,  22.49511583,  10.90891806,  18.99525417,
            21.57165972,   6.687755  ,   6.52137028,  15.86534639,
            18.53823556,   6.32563583,  12.99365833,  11.06817056,
            17.29261306,  15.31288556,  19.16236667,  10.38483333,
            14.51442222,  17.01413611,   6.96102278,  15.98508611,
            16.5287    ,  15.26533889,  20.83520278,  17.21952056,
             7.3225775 ,  16.42534361,  14.38649722,  21.63573111,  16.19249444]
    data = np.array(data)*60*60
    plot_clock(data)
    plt.show()

def plot_clock(data):
    def hour_formatAM(x, p):
        hour = x * 6 / np.pi
        return '{:0.0f}:00'.format(hour) if x > 0 else '12:00'

    def hour_formatPM(x, p):
        hour = x * 6 / np.pi
        return '{:0.0f}:00'.format(hour + 12) if x > 0 else '24:00'

    def plot(ax, theta, counts, formatter):
        colors = plt.cm.jet(theta / 12.0)
        ax.bar(theta, counts, width=np.pi/6, color=colors, alpha=0.5)
        ax.xaxis.set_major_formatter(tkr.FuncFormatter(formatter))

    plt.rcParams['font.size'] = 8

    bins = np.r_[0, 0.5:12, 12, 12.5:24,  23.99999]
    data = np.array(data) / (60*60)
    counts = np.histogram(data,bins)[0]

    counts[13] += counts[0]
    counts[-1] += counts[13]

    fig, axes = plt.subplots(ncols=2, figsize=(5.5, 3), dpi=200,
                             subplot_kw=dict(projection='polar'))
    fig.subplots_adjust(wspace=0.4)
    for ax in axes:
        ax.set(theta_offset=np.pi/2, theta_direction=-1,
               xticks=np.arange(0, np.pi*2, np.pi/6),
               yticks=np.arange(1, counts.max()))

    plot(axes[0], bins[1:13] * np.pi / 6, counts[1:13], hour_formatAM)
    plot(axes[1], bins[14:26] * np.pi / 6, counts[14:26], hour_formatPM)

main()



如果要避免刻度标签未对齐,可以根据其位置设置水平对齐方式:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as tkr

def main():
    data = [ 10.49531611,  22.49511583,  10.90891806,  18.99525417,
            21.57165972,   6.687755  ,   6.52137028,  15.86534639,
            18.53823556,   6.32563583,  12.99365833,  11.06817056,
            17.29261306,  15.31288556,  19.16236667,  10.38483333,
            14.51442222,  17.01413611,   6.96102278,  15.98508611,
            16.5287    ,  15.26533889,  20.83520278,  17.21952056,
             7.3225775 ,  16.42534361,  14.38649722,  21.63573111,  16.19249444]
    data = np.array(data)*60*60
    axes = plot_clock(data)
    for ax in axes:
        realign_polar_xticks(ax)
    plt.show()

def realign_polar_xticks(ax):
    for x, label in zip(ax.get_xticks(), ax.get_xticklabels()):
        if np.sin(x) > 0.1:
            label.set_horizontalalignment('left')
        if np.sin(x) < -0.1:
            label.set_horizontalalignment('right')

def plot_clock(data):
    def hour_formatAM(x, p):
        hour = x * 6 / np.pi
        return '{:0.0f}:00'.format(hour) if x > 0 else '12:00'

    def hour_formatPM(x, p):
        hour = x * 6 / np.pi
        return '{:0.0f}:00'.format(hour + 12) if x > 0 else '24:00'

    def plot(ax, theta, counts, formatter):
        colors = plt.cm.jet(theta / 12.0)
        ax.bar(theta, counts, width=np.pi/6, color=colors, alpha=0.5)
        ax.xaxis.set_major_formatter(tkr.FuncFormatter(formatter))

    plt.rcParams['font.size'] = 8

    bins = np.r_[0, 0.5:12, 12, 12.5:24,  23.99999]
    data = np.array(data) / (60*60)
    counts = np.histogram(data,bins)[0]

    counts[13] += counts[0]
    counts[-1] += counts[13]

    fig, axes = plt.subplots(ncols=2, figsize=(5.5, 3), dpi=200,
                             subplot_kw=dict(projection='polar'))
    fig.subplots_adjust(wspace=0.5)

    for ax in axes:
        ax.set(theta_offset=np.pi/2, theta_direction=-1,
               xticks=np.arange(0, np.pi*2, np.pi/6),
               yticks=np.arange(1, counts.max()))

    plot(axes[0], bins[1:13] * np.pi / 6, counts[1:13], hour_formatAM)
    plot(axes[1], bins[14:26] * np.pi / 6, counts[14:26], hour_formatPM)
    return axes

main()

最后,如果要“正确”执行此操作,则无论theta方向和偏移如何,都可以执行以下操作:
def realign_polar_xticks(ax):
    for theta, label in zip(ax.get_xticks(), ax.get_xticklabels()):
        theta = theta * ax.get_theta_direction() + ax.get_theta_offset()
        theta = np.pi/2 - theta
        y, x = np.cos(theta), np.sin(theta)
        if x >= 0.1:
            label.set_horizontalalignment('left')
        if x <= -0.1:
            label.set_horizontalalignment('right')
        if y >= 0.5:
            label.set_verticalalignment('bottom')
        if y <= -0.5:
            label.set_verticalalignment('top')

关于python + matplotlib : how to insert more space between the axis and the tick labels in a polar chart?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20222436/

10-09 09:35