具有dB刻度和负角度值的半极坐标图(方向性模式)

2024-06-06 13:02:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要分析/呈现我的测量数据的方向性图。从-90°到90°的角度(0°必须显示为北),R值也应为负值(分贝刻度)。在

我试过了 Floating axis example 目前我使用的是来自here的分数极轴()。代码不错,但我不明白。 但我还是不知道如何让它为我的目的工作。我还是个菜鸟,我找不到合适(简单)的解决方案。在

如果我试图将rlimits设置为(-20,0),python(spyder)崩溃。在

如果我试着把θ设为(-90,90),它可以工作,但是它旋转了90度,我需要0到东北,而不是东方。我试图增加一个额外的旋转角度,但我不知道怎么做。所有尝试都失败了。在

这里我在一个文件中放了一个例子。在

    """Demo of polar plot of arbitrary theta. This is a workaround for MPL's polar plot limitation
to a full 360 deg.

Based on http://matplotlib.org/mpl_toolkits/axes_grid/examples/demo_floating_axes.py
"""

from __future__ import division
from __future__ import print_function

import numpy as np
import matplotlib.pyplot as plt

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
from mpl_toolkits.axisartist.floating_axes import GridHelperCurveLinear, FloatingSubplot


def fractional_polar_axes(f, thlim=(0, 180), rlim=(0, 1), step=(30, 0.2),
                          thlabel='theta', rlabel='r', ticklabels=True):
    """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

    # scale degrees to radians:
    tr_scale = Affine2D().scale(np.pi/180., 1.)

    tr = tr_scale +  PolarAxes.PolarTransform()

    theta_grid_locator = angle_helper.LocatorDMS((th1-th0)//thstep)
    r_grid_locator = MaxNLocator((r1-r0)//rstep)
    theta_tick_formatter = angle_helper.FormatterDMS()

    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=None)

    a = FloatingSubplot(f, 111, grid_helper=grid_helper)
    f.add_subplot(a)
     # adjust x axis (theta):
    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")

    # 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=ticklabels, 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)
    # 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]
    for th in thticks[1:-1]: # all but the first and last
        auxa.plot([th, th], [r0, r1], '--', c='grey', zorder=-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', 2, 'black'
        else:
            ls, lw, color = 'dashed', 1, 'grey'
        # 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=-1))
    return auxa

# my own code
#import numpy as np
#import polar_demo

theta =np.arange(-90., 91, 1) 
v = np.array([0.003029756, 0.003278999,  0.003891915,  0.003397707,  0.004088546,  0.004237963, 0.004576779, 0.005137577, 0.005557515, 0.006002701, 0.006251121, 0.006115849, 0.006220946, 0.006702619, 0.006487209, 0.006965977, 0.006961644, 0.006344132, 0.006135627, 0.005891294, 0.005498547, 0.005860019, 0.005952021, 0.005632097, 0.006041763, 0.006388289, 0.005938246, 0.006262405, 0.006516638, 0.006149105, 0.006040157, 0.005713938, 0.004380804, 0.003073705, 0.002339913, 0.002011604, 0.002419609, 0.002411165, 0.002088174, 0.002099459, 0.003443293, 0.004828490, 0.005701596, 0.006000785, 0.007054744, 0.007375258, 0.007692269, 0.007849744, 0.007883301, 0.008043624, 0.007892837, 0.008227520, 0.008790336, 0.009058158, 0.008707412, 0.008264507, 0.007942288, 0.007729781, 0.007153670, 0.006177770, 0.005930654, 0.006878120, 0.008224512, 0.009333521, 0.009887548, 0.010679240, 0.012035168, 0.013572552, 0.014649003, 0.016023062, 0.017153479, 0.017482565, 0.016855999, 0.016556822, 0.017210254, 0.018402022, 0.020348028, 0.022555166, 0.024685826, 0.026662607, 0.030263813, 0.034134498, 0.037835099, 0.041901713, 0.045083964, 0.047717820, 0.050501022, 0.052132071, 0.053025513, 0.054776115, 0.054434939, 0.053598260, 0.052045371, 0.049853666, 0.047209907, 0.043862515, 0.040879899, 0.038089268, 0.034993134, 0.032141467, 0.028673013, 0.025357649, 0.021715866, 0.018649413, 0.016134787, 0.016080060, 0.016607230, 0.017332138, 0.017719092, 0.017767164, 0.017388066, 0.016922674, 0.016537550, 0.016521571, 0.016329574, 0.016087252, 0.015333185, 0.014314958, 0.012862059, 0.011321168, 0.009755944, 0.009256364, 0.008445667, 0.007593351, 0.006349995, 0.005493491, 0.004557222, 0.004642170, 0.005364849, 0.006375077, 0.006955036, 0.006871354, 0.006216022, 0.005252610,  0.004769276,  0.004932222,  0.005148679,  0.005305222,  0.004644044,  0.003616387,  0.002414268,  0.001617685,  0.002374725,  0.002971222,  0.002913218,  0.002719645,  0.002346166,  0.002575187,  0.002987921,  0.003136834,  0.003183764,  0.003413871,  0.003350896,  0.003073886,  0.002892891,  0.002265416,  0.001655378,  0.001560327,  0.001968299,  0.001995381,  0.001919509,  0.001992721,  0.002116618,  0.001886192,  0.001977474,  0.002126476,  0.002761516,  0.002651429,  0.002898811,  0.003334228,  0.003127383,  0.002904569,  0.003357476,  0.003112309,  0.003140989,  0.003023685,  0.002587393, 0.002277524, 0.002075252, 0.001928620, 0.002257961])
PointerLine    = np.zeros((181))        
Angle = 0
MaxValue = 60
v = v *1000
#v=20*np.log10(v/max(v)) #logarithmic scale -20dB .. 0 dB
PointerLine[Angle+90] = MaxValue


f1 = plt.figure(facecolor='white')
a1 = fractional_polar_axes(f1, (-90, 90.), (0, MaxValue), (10, 10),None, 'measured voltage (mV)', True)
MyTitle= 'Target angle %4.1f$^\circ$' %Angle
f1.suptitle( MyTitle, y=0.95)
a1.plot(theta, v, 'b')
a1.plot(theta, PointerLine,'r')
OutFileName='out_mv/angle_%02.2f' % Angle
#f1.savefig(OutFileName+'.eps')
f1.savefig('test.png', dpi=300)
plt.show()

Tags: fromimporthelperforplottopnpgrid
3条回答

随着pyplot中极坐标图的发展,这是Joma答案的更新。1/2圆和整圆的选项(参见前面的注释栏pp.显示)包括在内。在

这应该是一个评论vs一个完整的答案,但我缺乏声誉点。在

from __future__ import division
import numpy as np
from numpy import pi
import matplotlib.pyplot as pp

# normalize and convert to dB
dbnorm = lambda x: 20*np.log10(np.abs(x)/np.max(x));

# generate example data
# some angles
alpha = np.arange(-90, 90, 0.01);
x = np.deg2rad(alpha)
dir_function = dbnorm(np.sinc(x))

# plot
ax = pp.subplot(111, polar=True)
# set zero north
ax.set_theta_zero_location('N')
ax.set_theta_direction('clockwise')
pp.plot(np.deg2rad(alpha), dir_function)
ax.set_ylim(-20,0)
ax.set_yticks(np.array([-20, -12, -6, 0]))

# The new way per https://github.com/matplotlib/matplotlib/pull/4699
ax.set_xticks(np.array([-90, -45, 0, 45, 90])/180*pi)
ax.set_thetalim(-1/2*np.pi, 1/2*np.pi)


# Or if you still want a full 360 radiation pattern uncomment these
# ax.set_xticks(np.array([-90, -45, 0, 45, 90])/180*pi)
# ax.set_thetalim(-np.pi, np.pi)

pp.show()

resulting in

从你的标题来看,我认为这不是你想要的,因为它画了一个完整的圆圈。不考虑半地块要求,这可能是一个可行的解决方案:

from __future__ import division
import numpy as np
from numpy import pi
import matplotlib.pyplot as pp

# normalize and convert to dB
dbnorm = lambda x: 20*np.log10(np.abs(x)/np.max(x));

# generate example data
# some angles
alpha = np.arange(-90, 90, 0.01);
x = np.deg2rad(alpha)
dir_function = dbnorm(np.sinc(x))

# plot
ax = pp.subplot(111, polar=True)
# set zero north
ax.set_theta_zero_location('N')
ax.set_theta_direction('clockwise')
pp.plot(np.deg2rad(alpha), dir_function)
ax.set_ylim(-20,0)
ax.set_yticks(np.array([-20, -12, -6, 0]))
ax.set_xticks(np.array([0, -45, -90, np.nan, np.nan, np.nan, 90, 45])/180*pi)
pp.show()

它将描绘: enter image description here

我找到了一个解决旋转问题的方法:我加上tr_rotate和thta_offset

def fractional_polar_axes(f, thlim=(0, 180), rlim=(0, 1), step=(30, 0.2),
                      thlabel='theta', rlabel='r', ticklabels=True, theta_offset=0):
...
tr_rotate = Affine2D().translate(theta_offset, 0)
# scale degrees to radians:
tr_scale = Affine2D().scale(np.pi/180., 1.)

tr = tr_rotate + tr_scale +  PolarAxes.PolarTransform()

零点是θ偏移=90,在正确的位置。在

r的负值是可以的。“正常”极坐标图(ax=plt.子批次(111,polar=True)它起作用了。在

相关问题 更多 >