|
48 | 48 | sys.argv[i] = ' ' + arg |
49 | 49 | args = parser.parse_args() |
50 | 50 |
|
| 51 | +try: |
| 52 | + font = ImageFont.truetype("Vera.ttf", 10) |
| 53 | +except: |
| 54 | + print('Please download the Vera.ttf font and place it in the current directory.') |
| 55 | + sys.exit(1) |
| 56 | + |
| 57 | + |
51 | 58 | def frange(start, stop, step): |
52 | 59 | i = 0 |
53 | 60 | while (i*step + start <= stop): |
@@ -209,7 +216,8 @@ def rgb3(z): |
209 | 216 | return (int(c[0]*256),int(c[1]*256),int(c[2]*256)) |
210 | 217 |
|
211 | 218 | print("drawing") |
212 | | -img = Image.new("RGB", (len(freqs), len(times))) |
| 219 | +tape_height = 25 |
| 220 | +img = Image.new("RGB", (len(freqs), tape_height + len(times))) |
213 | 221 | pix = img.load() |
214 | 222 | x_size = img.size[0] |
215 | 223 | for line in raw_data(): |
@@ -237,18 +245,92 @@ def rgb3(z): |
237 | 245 | # fast check for nan/-inf |
238 | 246 | if not z >= min_z: |
239 | 247 | z = min_z |
240 | | - pix[x,y] = rgb2(z) |
| 248 | + pix[x,y+tape_height] = rgb2(z) |
| 249 | + |
| 250 | +def closest_index(n, m_list): |
| 251 | + error = max(m_list) |
| 252 | + best = -1 |
| 253 | + for i,m in enumerate(m_list): |
| 254 | + e2 = abs(m-n) |
| 255 | + if e2 > error: |
| 256 | + continue |
| 257 | + error = e2 |
| 258 | + best = i |
| 259 | + return best |
| 260 | + |
| 261 | +def word_aa(label, pt, fg_color, bg_color): |
| 262 | + f = ImageFont.truetype("Vera.ttf", pt*3) |
| 263 | + s = f.getsize(label) |
| 264 | + s = (s[0], int(s[1]*1.5)) # getsize lies |
| 265 | + w_img = Image.new("RGB", s, bg_color) |
| 266 | + w_draw = ImageDraw.Draw(w_img) |
| 267 | + w_draw.text((0, 0), label, font=f, fill=fg_color) |
| 268 | + return w_img.resize((s[0]//3, s[1]//3), Image.ANTIALIAS) |
| 269 | + |
| 270 | +def tape_lines(interval, y1, y2, used=set()): |
| 271 | + "returns the number of lines" |
| 272 | + low_f = (min(freqs) // interval) * interval |
| 273 | + high_f = (1 + max(freqs) // interval) * interval |
| 274 | + hits = 0 |
| 275 | + for i in range(int(low_f), int(high_f), int(interval)): |
| 276 | + if i in used: |
| 277 | + continue |
| 278 | + if not (min(freqs) < i < max(freqs)): |
| 279 | + continue |
| 280 | + x = closest_index(i, freqs) |
| 281 | + hits += 1 |
| 282 | + draw.line([x,y1,x,y2], fill='black') |
| 283 | + used.add(i) |
| 284 | + return hits |
| 285 | + |
| 286 | +def tape_text(interval, y, used=set()): |
| 287 | + low_f = (min(freqs) // interval) * interval |
| 288 | + high_f = (1 + max(freqs) // interval) * interval |
| 289 | + for i in range(int(low_f), int(high_f), int(interval)): |
| 290 | + if i in used: |
| 291 | + continue |
| 292 | + if not (min(freqs) < i < max(freqs)): |
| 293 | + continue |
| 294 | + x = closest_index(i, freqs) |
| 295 | + s = str(i) |
| 296 | + if interval >= 1e6: |
| 297 | + s = '%iM' % (i/1e6) |
| 298 | + elif interval > 1000: |
| 299 | + s = '%ik' % ((i/1e3) % 1000) |
| 300 | + else: |
| 301 | + s = '%i' % (i%1000) |
| 302 | + w = word_aa(s, tape_pt, 'black', 'yellow') |
| 303 | + img.paste(w, (x - w.size[0]//2, y)) |
| 304 | + used.add(i) |
241 | 305 |
|
242 | 306 | print("labeling") |
| 307 | +tape_pt = 10 |
243 | 308 | draw = ImageDraw.Draw(img) |
244 | 309 | font = ImageFont.load_default() |
245 | 310 | pixel_width = step |
246 | | -for label in labels: |
247 | | - y = 10 |
248 | | - #x = freqs.index(label) |
249 | | - x = int((label-min(freqs)) / pixel_width) |
250 | | - s = '%.3fMHz' % (label/1000000.0) |
251 | | - draw.text((x, y), s, font=font, fill='white') |
| 311 | + |
| 312 | +draw.rectangle([0,0,img.size[0],tape_height], fill='yellow') |
| 313 | +min_freq = min(freqs) |
| 314 | +max_freq = max(freqs) |
| 315 | +delta = max_freq - min_freq |
| 316 | +width = len(freqs) |
| 317 | +label_base = 8 |
| 318 | + |
| 319 | +for i in range(8, 0, -1): |
| 320 | + hits = range(0, int(2500e6), int(10**i)) |
| 321 | + hits = [j for j in hits if min_freq<j<max_freq] |
| 322 | + if len(hits) >= 4: |
| 323 | + label_base = i |
| 324 | + break |
| 325 | +label_base = 10**label_base |
| 326 | + |
| 327 | +for scale,y in [(1,10), (5,15), (10,19), (50,22), (100,24), (500, 25)]: |
| 328 | + hits = tape_lines(label_base/scale, y, tape_height) |
| 329 | + pixels_per_hit = width / hits |
| 330 | + if pixels_per_hit > 50: |
| 331 | + tape_text(label_base/scale, y-tape_pt) |
| 332 | + if pixels_per_hit < 6: |
| 333 | + break |
252 | 334 |
|
253 | 335 | if args.time_tick: |
254 | 336 | label_last = start |
|
0 commit comments