|
47 | 47 |
|
48 | 48 | </pre> |
49 | 49 | </details> |
50 | | -<details><summary><span class ='def signature'> def plot_pattern_gains(model, azimuth_deg = None, elevation_deg = None, components = ['vert_gain_dBi', 'horiz_gain_dBi'], gain_scale_range_dB = 30):</span></summary> |
51 | | -<pre class ='def content'> import matplotlib.pyplot as plt |
| 50 | +<details><summary><span class ='def signature'>🧾 def plot_total_gain(model):</span></summary> |
| 51 | +<pre class ='def content'></pre> |
| 52 | +<details><summary><span class ='docstring signature'> docstring</span></summary> |
| 53 | +<pre class ='docstring content'> This is a very basic plot routine providing polar and rectangular plots |
| 54 | + with gain range covering 40 dB max to min. |
| 55 | + Later versions of necbol will include more customisable plot functions |
| 56 | + and the ability to save output data in a suitable format for onward analysis |
| 57 | +</pre> |
| 58 | +</details> |
| 59 | +<details><summary><span class ='body signature'> body</span></summary> |
| 60 | +<pre class ='body content'> import matplotlib.pyplot as plt |
52 | 61 | import numpy as np |
53 | 62 |
|
54 | | - if(elevation_deg is not None and azimuth_deg is not None): |
55 | | - Print("Can't plot a 3D pattern, please select azimuth or elevation only") |
56 | | - return |
| 63 | + pattern_data = _read_radiation_pattern(model.nec_out, elevation_deg = model.el_datum_deg) |
| 64 | + elevation_deg = model.el_datum_deg |
| 65 | + component = 'total_gain_dBi' |
| 66 | + |
| 67 | + # Filter data for fixed elevation |
| 68 | + print(f"Plotting gain for elevation = {elevation_deg}") |
| 69 | + az_cut = [d for d in pattern_data if abs(d['elevation_deg'] - model.el_datum_deg) < 0.1] |
| 70 | + |
| 71 | + # Extract azimuth (phi) and gain |
| 72 | + az_deg = [d['azimuth_deg'] for d in az_cut] |
| 73 | + gain_db = [d[component] for d in az_cut] |
| 74 | + max_gain = np.max(gain_db) |
| 75 | + |
| 76 | + title = f'{component} at elevation = {elevation_deg}° for {model.model_name}' |
| 77 | + |
| 78 | + az_rad = np.radians(az_deg) |
| 79 | + fig, ax = plt.subplots(subplot_kw={'projection': 'polar'}) |
| 80 | + ax.plot(az_rad, gain_db, label=title) |
| 81 | + ax.set_title(title) |
| 82 | + ax.grid(True) |
| 83 | + ax.set_rmax(max_gain) |
| 84 | + ax.set_rmin(max_gain-40) |
| 85 | + ax.set_rlabel_position(90) |
| 86 | + |
| 87 | + plt.show() |
57 | 88 |
|
58 | | - if (elevation_deg is None and azimuth_deg is None): |
59 | | - elevation_deg = model.el_datum_deg |
60 | 89 |
|
61 | | - title = model.model_name |
62 | 90 |
|
| 91 | +#================================================================== |
| 92 | +# Internal functions |
| 93 | +#================================================================== |
| 94 | + |
| 95 | +import numpy as np |
| 96 | +import copy |
| 97 | + |
| 98 | +</pre> |
| 99 | +</details> |
| 100 | +</details> |
| 101 | +<details><summary><span class ='def signature'> def _plot_pattern_gains(pattern_data, azimuth_deg = None, elevation_deg = None, components = ['gain_total_dBi']):</span></summary> |
| 102 | +<pre class ='def content'> import matplotlib.pyplot as plt |
| 103 | + import numpy as np |
| 104 | + |
63 | 105 | # Filter data for fixed elevation (theta) |
64 | 106 | if(elevation_deg is not None): |
65 | 107 | print(f"Plotting gain for elevation = {elevation_deg}") |
66 | | - pattern_data = _read_radiation_pattern(model.nec_out, azimuth_deg = azimuth_deg, elevation_deg = None) |
67 | | - |
68 | 108 | cut = [d for d in pattern_data if abs(d['elevation_deg'] - elevation_deg) < 0.1] |
69 | 109 | angle_deg = [d['azimuth_deg'] for d in cut] |
70 | | - title += f' elevation = {elevation_deg}°' |
| 110 | + title = f'elevation = {elevation_deg}°' |
71 | 111 |
|
72 | 112 | # Filter data for fixed azimuth (phi) |
73 | 113 | if(azimuth_deg is not None): |
74 | 114 | print(f"Plotting gain for azimuth = {azimuth_deg}") |
75 | | - pattern_data = _read_radiation_pattern(model.nec_out, azimuth_deg = None, elevation_deg = elevation_deg) |
76 | 115 | cut = [d for d in pattern_data if abs(d['azimuth_deg'] - azimuth_deg) < 0.1] |
77 | 116 | angle_deg = [d['elevation_deg'] for d in cut] |
78 | | - title += f' azimuth = {azimuth_deg}°' |
| 117 | + title = f'azimuth = {azimuth_deg}°' |
79 | 118 |
|
80 | 119 | fig, ax = plt.subplots(subplot_kw={'projection': 'polar'}) |
81 | | - |
82 | | - scl_max = -100 |
83 | | - for comp in components: |
84 | | - gain = [d[comp] for d in cut] |
85 | | - scl_max = max(scl_max,max(gain)) |
86 | | - angle_rad = np.radians(angle_deg) |
87 | | - ax.plot(angle_rad, gain, label = comp) |
88 | | - print(comp, f" max gain: {max(gain)}") |
89 | | - ax.legend() |
| 120 | + angle_rad = np.radians(angle_deg) |
| 121 | + v_gain_db = [d['vert_gain_dBi'] for d in cut] |
| 122 | + h_gain_db = [d['horiz_gain_dBi'] for d in cut] |
| 123 | + ax.plot(angle_rad, v_gain_db, label=title) |
| 124 | + ax.plot(angle_rad, h_gain_db, label=title) |
90 | 125 | ax.set_title(title) |
91 | 126 | ax.grid(True) |
| 127 | + |
| 128 | + vmax = max(v_gain_db) |
| 129 | + hmax = max(h_gain_db) |
92 | 130 |
|
93 | | - ax.set_rmax(scl_max) |
94 | | - ax.set_rmin(scl_max - gain_scale_range_dB ) |
| 131 | + print(vmax,hmax) |
| 132 | + pmax = max(vmax,hmax) |
| 133 | + |
| 134 | + ax.set_rmax(pmax) |
| 135 | + ax.set_rmin(pmax-40) |
95 | 136 | ax.set_rlabel_position(90) |
96 | 137 |
|
97 | 138 | # Enable interactive mode for non-blocking plotting |
|
102 | 143 |
|
103 | 144 |
|
104 | 145 |
|
105 | | - |
106 | | -#================================================================== |
107 | | -# Internal functions |
108 | | -#================================================================== |
109 | | - |
110 | | -import numpy as np |
111 | | -import copy |
112 | | - |
113 | | - |
114 | | - |
115 | 146 | </pre> |
116 | 147 | </details> |
117 | 148 | <details><summary><span class ='def signature'> def _get_complex_component(pat_data, component):</span></summary> |
|
0 commit comments