Skip to main content
 首页 » 编程设计

python之如何使用 matplotlib 将半极 map 设置为北方

2024年11月01日29linjiqin

我有一个生成半极坐标图的函数(基于此:https://gist.github.com/kanhua/fce2421c2c4eb356a9d1d9e1cb3f61fc) 通过使用 matplotlib.transforms.Affine2D、matplotlib.projections.PolarAxes 和 mpl_toolkits.axisartist。

这是我的函数的代码:

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib 
from matplotlib.transforms import Affine2D 
from matplotlib.projections import PolarAxes 
from mpl_toolkits.axisartist import angle_helper 
from mpl_toolkits.axisartist.grid_finder import MaxNLocator, DictFormatter 
from mpl_toolkits.axisartist.floating_axes import GridHelperCurveLinear, FloatingSubplot 
 
def fractional_polar_axes(f, thlim=(-90, 90), rlim=(0, .48),step=(30, 0.12),thlabel='J-H vs J slope', rlabel='length', ticklabels=True, theta_offset=0, rlabels = None): 
    ''' 
        Return polar axes that adhere to desired theta (in deg) and r limits.  
        steps for theta and r are really just hints for the locators. 
    ''' 
    th0, th1 = thlim # deg 
    r0, r1 = rlim 
    thstep, rstep = step 
    tr_rotate = Affine2D().translate(theta_offset, 0) 
    # scale degrees to radians: 
    tr_scale = Affine2D().scale(np.pi/180., 1.) 
    pa = PolarAxes 
    tr = tr_rotate + tr_scale + pa.PolarTransform() 
    theta_grid_locator = angle_helper.LocatorDMS((th1-th0)//thstep) 
    r_grid_locator = MaxNLocator((r1-r0)//rstep) 
    theta_tick_formatter = angle_helper.FormatterDMS() 
    if rlabels: 
        rlabels = DictFormatter(rlabels) 
 
    grid_helper = GridHelperCurveLinear(tr, 
                                        extremes=(th0, th1, r0, r1), 
                                        grid_locator1=theta_grid_locator, 
                                        grid_locator2=r_grid_locator, 
                                        tick_formatter1=theta_tick_formatter, 
                                        tick_formatter2=rlabels) 
    a = FloatingSubplot(f, 111, grid_helper=grid_helper) 
    f.add_subplot(a) 
    # adjust x axis (theta): 
    print(a) 
    a.axis["bottom"].set_visible(False) 
    a.axis["top"].set_axis_direction("bottom") # tick direction 
    a.axis["top"].toggle(ticklabels=ticklabels, label=bool(thlabel)) 
    a.axis["top"].major_ticklabels.set_axis_direction("top") 
    a.axis["top"].label.set_axis_direction("top") 
    a.axis["top"].major_ticklabels.set_pad(10) 
    # adjust y axis (r): 
    a.axis["left"].set_axis_direction("bottom") # tick direction 
    a.axis["right"].set_axis_direction("top") # tick direction 
    a.axis["left"].toggle(ticklabels=True, label=bool(rlabel)) 
    # add labels: 
    a.axis["top"].label.set_text(thlabel) 
    a.axis["left"].label.set_text(rlabel) 
    # create a parasite axes whose transData is theta, r: 
    auxa = a.get_aux_axes(tr) 
    print(auxa) 
    # make aux_ax to have a clip path as in a?: 
    auxa.patch = a.patch  
    # this has a side effect that the patch is drawn twice, and possibly over some other 
    # artists. So, we decrease the zorder a bit to prevent this: 
    a.patch.zorder = -2 
 
    # add sector lines for both dimensions: 
    thticks = grid_helper.grid_info['lon_info'][0] 
    rticks = grid_helper.grid_info['lat_info'][0] 
    print(grid_helper.grid_info['lat_info']) 
    for th in thticks[1:-1]: # all but the first and last 
        auxa.plot([th, th], [r0, r1], ':', c='k', zorder=-1, lw=1.) 
    for ri, r in enumerate(rticks): 
        # plot first r line as axes border in solid black only if it  isn't at r=0 
        if ri == 0 and r != 0: 
            ls, lw, color = 'solid', 1, 'k' 
        else: 
            ls, lw, color = 'dashed', 0.5, 'k' 
        # From http://stackoverflow.com/a/19828753/2020363 
        auxa.add_artist(plt.Circle([0, 0], radius=r, ls=ls, lw=lw, color=color,  
                        fill=False,transform=auxa.transData._b, zorder=1000)) 
 
    return auxa 

通过这样调用函数:

f1 = plt.figure(facecolor='white',figsize = (5,5),dpi=100) 
a1 = fractional_polar_axes(f1, thlim=(-90,90),rlim=(0, 1.4),step=(30, 0.30), 
                           theta_offset=90,thlabel='J vs. J-H') 

我制作了以下情节:

问题是:我想制作一个与这个非常相似的极坐标图,但我希望 theta 轴从 90deg 到 -90deg(从右到左),这与我目前的功能相反情节。

有谁知道如何反转绘制 theta 的方向?

我知道 matplotlib.projections.PolarAxes 有一个名为 theta_direction 的参数,默认设置为 1,但我不知道代码在哪里这应该去。

请您参考如下方法:

您可以使用以下方法实现相同的效果:

fig = plt.figure() 
ax = fig.add_subplot(111, projection='polar', xlim=(-90, 90)) 
ax.set_theta_direction(-1) # change direction to CCW 
ax.set_thetamin(-90) # set the limits 
ax.set_thetamax(90) 
ax.set_theta_offset(.5*np.pi) # point the origin towards the top 
ax.set_thetagrids(range(-90, 120, 30)) # set the gridlines 
ax.set_title('J vs. J-H', pad=-50) # add title and relocate negative value lowers the location 
ax.set_xlabel('xlabel') 
ax.xaxis.set_label_coords(0.5, 0.15) # change the location of the xlabel to given x, y locations w.r.t. the entire figure