首页 > 解决方案 > Matplotlib polar 未按预期绘制

问题描述

我正在尝试插入笛卡尔图的极坐标“版本”。这是它的样子(根据在 Matlab 中完成的类似程序):

在此处输入图像描述

这里有足够的代码来显示我得到的怪异:

from scipy import pi, sin, cos, log
from numpy import radians as rad
from numpy import log10, linspace
from matplotlib import pyplot as plt


############## Inputs ##############

#Beamwidth, in degrees
BW = 5

############## Constants for calculations ##############
# 0 = uniform/sin, 1 = cos, 2 = cos^2, etc


#Peak Pattern break points, from Table 3
p0, p1, p2, p3, p4 = -5.75, -14.4, -22.3, -31.5, -39.4


#Average pattern break points, from Table 3
a0, a1 ,a2, a3, a4 = -12.16, -20.6, -29, -37.6, -42.5


#Constant added to peak pattern to convert it to average, from Table 3
c0, c1, c2, c3, c4 = -3.72, -4.32, -4.6, -4.2, -2.61


#Mask floor levels, from Table 3
floor0, floor1, floor2, floor3, floor4 = -30, -50, -60, -70, -80


############## Calculations ##############

#Lists for plotting purposes

u_x = list(linspace(0,90,500))

u0_norm_y = list()
u0_peak_y = list()
u0_avg_y = list()

##Calculations start

for ang in u_x: 

########## Uniform

    u0 = pi * 50.8 * sin(rad(ang)) / BW

    def u0_norm(ang):
        if ang == 0:
            return 0
        else:
            return 20 * log10(abs(sin(u0) / u0))


    def u0_peak(ang, u0_norm):
        if ang == 0:
            return 0
        elif u0_norm(ang) > p0:
            return u0_norm(ang)
        elif -8.584 * log(2.876 * ang / BW) > floor0:
            return -8.584 * log(2.876 * ang / BW)
        else:
            return floor0

    def u0_avg(ang, u0_norm):
        if ang == 0:
            return 0
        elif u0_norm(ang) > a0:
            return u0_norm(ang)
        elif -8.584 * log(2.876 * ang / BW) + c0 > floor0:
            return -8.584 * log(2.876 * ang / BW) + c0
        else:
            return floor0 

    u0_peak_y.append(u0_peak(ang, u0_norm))
    u0_norm_y.append(u0_norm(ang))
    u0_avg_y.append(u0_avg(ang, u0_norm))

############## Plots ##############

#Uniform
fig1 = plt.figure()
ax1 = plt.subplot(121)
ax2 = plt.subplot(122, polar = True)

ax1.plot(u_x, u0_norm_y, label= "Normalized Pattern")
ax1.plot(u_x, u0_peak_y, label= "Peak")
ax1.plot(u_x, u0_avg_y, label= "Average")

ax1.set_title("Uniform Pattern")
ax1.set_xlabel("Angle (degrees)")
ax1.set_ylabel("Normalized Antenna Pattern (dB)")

ax2.set_theta_zero_location("N")
ax2.set_theta_direction(-1)
ax2.plot(u_x, u0_norm_y, label= "Normalized Pattern")
ax2.plot(u_x, u0_peak_y, label= "Peak")
ax2.plot(u_x, u0_avg_y, label= "Average")
ax2.set_thetamin(0)
ax2.set_thetamax(90)



ax1.grid(True)
plt.tight_layout()
plt.subplots_adjust(wspace = 0.4)

plt.show()

显然,有些事情出了大问题。我的情节实际上是一团糟。我假设极坐标图与笛卡尔图的创建方式在代码方面非常不同,但我无法找到任何关于此的真实细节。

标签: pythonmatplotlibplot

解决方案


您正在混淆弧度和度数(ImportanceOfBeingErnest 的直觉是正确的)。删除定义 u0 时对弧度的转换,直接将输入 u_x 转换为弧度。

from scipy import pi, sin, cos, log
from numpy import radians as rad
from numpy import log10, linspace
from matplotlib import pyplot as plt


############## Inputs ##############

#Beamwidth, in degrees
BW = 5

############## Constants for calculations ##############
# 0 = uniform/sin, 1 = cos, 2 = cos^2, etc


#Peak Pattern break points, from Table 3
p0, p1, p2, p3, p4 = -5.75, -14.4, -22.3, -31.5, -39.4


#Average pattern break points, from Table 3
a0, a1 ,a2, a3, a4 = -12.16, -20.6, -29, -37.6, -42.5


#Constant added to peak pattern to convert it to average, from Table 3
c0, c1, c2, c3, c4 = -3.72, -4.32, -4.6, -4.2, -2.61


#Mask floor levels, from Table 3
floor0, floor1, floor2, floor3, floor4 = -30, -50, -60, -70, -80

############## Calculations ##############

#Lists for plotting purposes

u_x = list(linspace(0,rad(90),500))


u0_norm_y = list()
u0_peak_y = list()
u0_avg_y = list()

##Calculations start

for ang in u_x:

########## Uniform

    u0 = pi * 50.8 * sin((ang)) / BW

    def u0_norm(ang):
        if ang == 0:
            return 0
        else:
            return 20 * log10(abs(sin(u0) / u0))


    def u0_peak(ang, u0_norm):
        if ang == 0:
            return 0
        elif u0_norm(ang) > p0:
            return u0_norm(ang)
        elif -8.584 * log(2.876 * ang / BW) > floor0:
            return -8.584 * log(2.876 * ang / BW)
        else:
            return floor0

    def u0_avg(ang, u0_norm):
        if ang == 0:
            return 0
        elif u0_norm(ang) > a0:
            return u0_norm(ang)
        elif -8.584 * log(2.876 * ang / BW) + c0 > floor0:
            return -8.584 * log(2.876 * ang / BW) + c0
        else:
            return floor0

    u0_peak_y.append(u0_peak(ang, u0_norm))
    u0_norm_y.append(u0_norm(ang))
    u0_avg_y.append(u0_avg(ang, u0_norm))

############## Plots ##############

#Uniform
fig1 = plt.figure()
ax1 = plt.subplot(121)
ax2 = plt.subplot(122, polar = True)

ax1.plot(u_x, u0_norm_y, label= "Normalized Pattern")
ax1.plot(u_x, u0_peak_y, label= "Peak")
ax1.plot(u_x, u0_avg_y, label= "Average")

ax1.set_title("Uniform Pattern")
ax1.set_xlabel("Angle (degrees)")
ax1.set_ylabel("Normalized Antenna Pattern (dB)")

ax2.set_theta_zero_location("N")
ax2.set_theta_direction(-1)
ax2.plot(u_x, u0_norm_y, label= "Normalized Pattern")
ax2.plot(u_x, u0_peak_y, label= "Peak")
ax2.plot(u_x, u0_avg_y, label= "Average")
ax2.set_thetamin(0)
ax2.set_thetamax(90)



ax1.grid(True)
plt.tight_layout()
plt.subplots_adjust(wspace = 0.4)

plt.show()

结果

这是我认为相同代码的更好版本,几乎没有编辑。

from scipy import pi, sin, cos, log
from numpy import radians as rad
from numpy import log10, linspace
from matplotlib import pyplot as plt


############## Inputs ##############

#Beamwidth, in degrees
BW = 5

############## Constants for calculations ##############
# 0 = uniform/sin, 1 = cos, 2 = cos^2, etc


#Peak Pattern break points, from Table 3
p0, p1, p2, p3, p4 = -5.75, -14.4, -22.3, -31.5, -39.4


#Average pattern break points, from Table 3
a0, a1 ,a2, a3, a4 = -12.16, -20.6, -29, -37.6, -42.5


#Constant added to peak pattern to convert it to average, from Table 3
c0, c1, c2, c3, c4 = -3.72, -4.32, -4.6, -4.2, -2.61


#Mask floor levels, from Table 3
floor0, floor1, floor2, floor3, floor4 = -30, -50, -60, -70, -80


############## Calculations ##############

#Lists for plotting purposes

u_x = list(linspace(0,rad(90),500))


u0_norm_y = list()
u0_peak_y = list()
u0_avg_y = list()

##Function definition
def u0_norm(ang, u0):
    if ang == 0:
        return 0
    else:
        return 20 * log10(abs(sin(u0) / u0))


def u0_peak(ang, u0):
    if ang == 0:
        return 0
    elif u0_norm(ang, u0) > p0:
        return u0_norm(ang, u0)
    elif -8.584 * log(2.876 * ang / BW) > floor0:
        return -8.584 * log(2.876 * ang / BW)
    else:
        return floor0


def u0_avg(ang, u0):
    if ang == 0:
        return 0
    elif u0_norm(ang, u0) > a0:
        return u0_norm(ang, u0)
    elif -8.584 * log(2.876 * ang / BW) + c0 > floor0:
        return -8.584 * log(2.876 * ang / BW) + c0
    else:
        return floor0

for ang in u_x:

    ########## Uniform

    u0 = pi * 50.8 * sin(ang) / BW

    u0_peak_y.append(u0_peak(ang, u0))
    u0_norm_y.append(u0_norm(ang, u0))
    u0_avg_y.append(u0_avg(ang, u0))

    ############## Plots ##############

#Uniform
fig1 = plt.figure()
ax1 = plt.subplot(121)
ax2 = plt.subplot(122, polar = True)

ax1.plot(u_x, u0_norm_y, label= "Normalized Pattern")
ax1.plot(u_x, u0_peak_y, label= "Peak")
ax1.plot(u_x, u0_avg_y, label= "Average")

ax1.set_title("Uniform Pattern")
ax1.set_xlabel("Angle (radians)")
ax1.set_ylabel("Normalized Antenna Pattern (dB)")

ax2.set_theta_zero_location("N")
ax2.set_theta_direction(-1)
ax2.plot(u_x, u0_norm_y, label= "Normalized Pattern")
ax2.plot(u_x, u0_peak_y, label= "Peak")
ax2.plot(u_x, u0_avg_y, label= "Average")
ax2.set_thetamin(0)
ax2.set_thetamax(90)



ax1.grid(True)
plt.tight_layout()
plt.subplots_adjust(wspace = 0.4)

plt.show()

推荐阅读