# Signal Strength Heatmap

**URL:** <https://discussions.flightaware.com/t/signal-strength-heatmap/53109>\
**Category:** ADS-B Flight Tracking\
**Created:** [July 31, 2019, 5:02pm UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109 "2019-07-31T17:02:42Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![caius](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/caius/32/113839_2.png) [@caius](https://discussions.flightaware.com/u/caius)\
**Post date:** [July 31, 2019, 5:02pm UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/1 "2019-07-31T17:02:42Z")

</div>

I have written a script that captures data from dump1090-fa and plots a heatmap showing signal strength for each aircraft position. This example is plotted from about 15 hours of data.

 ![image](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/1/7/17e4b4d5185ee602f6a3dcba67e924f5374df236.png)

The script samples currently visible aircraft from the aircraft.json file and records signal strength and position to a file. Gnuplot is then used to plot the data.

The plot is fairly naive, in that it ignores proper map projections so bearings won’t be quite correct, however it should give a reasonable representation of what is going on. My antenna is in the loft space, so you can clearly see radio shadows caused by the brick walls and roof structure.

The script is available here:

```auto
https://raw.githubusercontent.com/caiusseverus/adsbcompare/master/heatmap.sh

```

Note that you should set your receiver latitude and longitude at the top of the script in order for its position to be marked on the plot.

Usage is simple - there are two options when running the command. The first sets the duration of data gathering in minutes, and the second sets the sample interval in seconds.

Example:

```auto
./heatmap.sh 1440 10

```

This will collect data for 24 hours, every 10 seconds. Obviously the shorter the interval, the more data points you get but the more storage it will use.

The example above was sampled every 3 seconds for 15 hours or so, giving a total of about 2 million data points. Large numbers aren’t a problem for gnuplot, it just takes a little while to crunch through it. The data file was about 50MB.

If you want to run the script for longer periods and not worry about having to stay logged in for it to complete, you can do this:

```auto
nohup ./heatmap.sh 1440 10 &

```

which will start the script running in the background and leave it running if you log out.

The collected data is saved in a file in the current directory called `heatmap-<date>`  
and the plot is also saved with the current date, but also copied to the dump1090 folder so it can be seen/saved from your browser at:  
`http://raspberrypi/dump1090-fa/data/heatmap.png`

You need to have gnuplot, and jq (think it is by default on raspbian) installed for this to work.

Scripts related to this are kept in this repository: [GitHub - caiusseverus/adsbcompare: Tools to plot and compare data gathered with graphs1090](https://github.com/caiusseverus/adsbcompare)

Edit:

Thanks to his modification, if you are running [timelapse1090](https://github.com/wiedehopf/timelapse1090) by @wiedehopf you can use the data already collected by that to produce plots without waiting to accumulate more data:

`bash heatmap.sh -1`

There is now a version that produces plots based on range and bearing, and also produces additional azimuth/elevation and range/altitude plots:

 ![image](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/b/a/ba8d0ab2887f33a408cb9ee988f0cf982d7077cb.png)

 ![image](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/3/0/308c3fc74c4a10abae8660e24d1c2df3fcfb07ab.png)

These can be produced with the script:

`https://raw.githubusercontent.com/caiusseverus/adsbcompare/master/polar.sh`

Usage and options are exactly the same as for heatmap.sh, however you need to have gawk and gnuplot 5.2 installed. Raspbian stretch users will need to do:

```auto
sudo apt install gawk
sudo apt install liblua5.3
curl -sO http://ftp.debian.org/debian/pool/main/g/gnuplot/gnuplot-data_5.2.6+dfsg1-3_all.deb
curl -sO http://ftp.debian.org/debian/pool/main/g/gnuplot/gnuplot-nox_5.2.6+dfsg1-3_armhf.deb
sudo dpkg -i ./gnuplot-data_5.2.6+dfsg1-3_all.deb
sudo dpkg -i ./gnuplot-nox_5.2.6+dfsg1-3_armhf.deb

```

Note that this involves doing a lot of calculations and so it takes some time to produce output ~15 minutes or so on a Pi 3 for a full 24 hours of data.

---

<div class="post-metadata">

**Author:** ![wiedehopf](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/wiedehopf/32/114045_2.png) [@wiedehopf](https://discussions.flightaware.com/u/wiedehopf)\
**Post date:** [July 31, 2019, 6:24pm UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/2 "2019-07-31T18:24:30Z")

</div>

> [@caius](#):
>
> The script samples currently visible aircraft from the aircraft.json file and records signal strength and position to a file.

How about restricting the planes to a certain altitude range?  
(alt\_baro is the relevant json entry for each aircraft)

Very nicely done!

---

<div class="post-metadata">

**Author:** ![caius](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/caius/32/113839_2.png) [@caius](https://discussions.flightaware.com/u/caius)\
**Post date:** [July 31, 2019, 6:46pm UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/3 "2019-07-31T18:46:48Z")

</div>

> [@wiedehopf](#):
>
> How about restricting the planes to a certain altitude range?  
> (alt\_baro is the relevant json entry for each aircraft)

That’s a good idea. I’ll probably do it by capturing all the data and filtering it later. I also want to switch the plot to use polar coordinates, since it makes adding things like range rings easier.

---

<div class="post-metadata">

**Author:** ![bramjacobse](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/bramjacobse/32/137180_2.png) [@bramjacobse](https://discussions.flightaware.com/u/bramjacobse)\
**Post date:** [July 31, 2019, 7:53pm UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/4 "2019-07-31T19:53:33Z")

</div>

1 hour capture 10 sec interval

 ![heatmap](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/4/9/499fb3fe9792b032239fe54e806881e96b252298.png)

---

<div class="post-metadata">

**Author:** ![modea](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/modea/32/93419_2.png) [@modea](https://discussions.flightaware.com/u/modea)\
**Post date:** [July 31, 2019, 8:27pm UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/5 "2019-07-31T20:27:22Z")

</div>

> [@caius](#):
>
> heatmap.png

Awesome - Thank you for making this! Ran it for about an hour just to see what it did

 ![heatmap](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/3/2/3210fe3fb852021897465d64be403f6c1a58403e.png)

---

<div class="post-metadata">

**Author:** ![Dav5049915](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/dav5049915/32/113540_2.png) [@Dav5049915](https://discussions.flightaware.com/u/Dav5049915)\
**Post date:** [July 31, 2019, 8:53pm UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/6 "2019-07-31T20:53:16Z")

</div>

This tool is gonna help me figure out what trees need to uhhhh fall down in the next storm

can’t wait to try it when I get home!

---

<div class="post-metadata">

**Author:** ![caius](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/caius/32/113839_2.png) [@caius](https://discussions.flightaware.com/u/caius)\
**Post date:** [July 31, 2019, 9:18pm UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/7 "2019-07-31T21:18:31Z")

</div>

> [@modea](#):
>
> Awesome - Thank you for making this! Ran it for about an hour just to see what it did

At the moment the RSSI scale is fixed. Since most of your signals seems to be pretty strong (you are using an Airspy?) you might want to change it to get a better spread of colours. Look for this line:

`set cbrange [-35:0]`

and change the left number to something close to what your weakest signals are.

At some point I’ll change the script to pick a range automatically.

---

<div class="post-metadata">

**Author:** ![modea](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/modea/32/93419_2.png) [@modea](https://discussions.flightaware.com/u/modea)\
**Post date:** [July 31, 2019, 9:29pm UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/8 "2019-07-31T21:29:44Z")

</div>

in this instance I’m using FA Blue stick + GPIOlabs pre-amp. I’ll dial it in now and let it run again.

---

<div class="post-metadata">

**Author:** ![Dav5049915](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/dav5049915/32/113540_2.png) [@Dav5049915](https://discussions.flightaware.com/u/Dav5049915)\
**Post date:** [August 1, 2019, 1:43am UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/9 "2019-08-01T01:43:50Z")

</div>

![heatmap](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/4/7/4777898a26a9c35e2de579ffec03907578299768.png)

1hr plot at 10sec with an airspy + LNA

This is AWESOME. Gonna run it for 24hrs and see what I get for dead zones.

---

<div class="post-metadata">

**Author:** ![obj](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/obj/32/118984_2.png) [@obj](https://discussions.flightaware.com/u/obj)\
**Post date:** [August 1, 2019, 3:31am UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/10 "2019-08-01T03:31:23Z")

</div>

Another thing that can be interesting is to do the same thing but with azimuth/elevation axes.

Here’s a really old example:

 ![elev](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/7/5/7578202a5801093692a184d87edd2318bb36a4de.png)

---

<div class="post-metadata">

**Author:** ![idoleo2001](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/idoleo2001/32/128777_2.png) [@idoleo2001](https://discussions.flightaware.com/u/idoleo2001)\
**Post date:** [August 1, 2019, 5:07am UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/11 "2019-08-01T05:07:33Z")

</div>

Is there any way to load “aircraft.json” get from this script ([Timelapse1090](https://discussions.flightaware.com/t/timelapse1090/50630)) inside Heatmap script?

Thanks a lot!

---

<div class="post-metadata">

**Author:** ![wiedehopf](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/wiedehopf/32/114045_2.png) [@wiedehopf](https://discussions.flightaware.com/u/wiedehopf)\
**Post date:** [August 1, 2019, 7:27am UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/12 "2019-08-01T07:27:15Z")

</div>

> [@idoleo2001](#):
>
> Is there any way to load “aircraft.json” get from this script ([Timelapse1090](https://discussions.flightaware.com/t/timelapse1090/50630))

Actually there is 🙂

You can use this modified version of the script:

```auto
https://raw.githubusercontent.com/wiedehopf/adsbcompare/use-timelapse-data/heatmap.sh

```

Invoke it like this:

```auto
bash heatmap.sh -1

```

 ![heatmap-2019-08-01](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/7/e/7e8dd07b1b9e933e5ae75fb63a711fcf5c5d75d8.png)

---

<div class="post-metadata">

**Author:** ![bramjacobse](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/bramjacobse/32/137180_2.png) [@bramjacobse](https://discussions.flightaware.com/u/bramjacobse)\
**Post date:** [August 1, 2019, 8:53am UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/13 "2019-08-01T08:53:55Z")

</div>

Heatmap

 ![heatmap-1](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/d/9/d9c548a7fc8ae8e0ebfbff4911eca3e6215908a5.png)

---

<div class="post-metadata">

**Author:** ![triggers](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/triggers/32/117248_2.png) [@triggers](https://discussions.flightaware.com/u/triggers)\
**Post date:** [August 1, 2019, 9:26am UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/14 "2019-08-01T09:26:32Z")

</div>

Lovely pieces of artwork to put on your wall:laughing:

Thanks Caius

---

<div class="post-metadata">

**Author:** ![caius](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/caius/32/113839_2.png) [@caius](https://discussions.flightaware.com/u/caius)\
**Post date:** [August 1, 2019, 10:21am UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/15 "2019-08-01T10:21:33Z")

</div>

> [@wiedehopf](#):
>
> You can use this modified version of the script:

Nice. I’ve updated the original script.

---

<div class="post-metadata">

**Author:** ![wiedehopf](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/wiedehopf/32/114045_2.png) [@wiedehopf](https://discussions.flightaware.com/u/wiedehopf)\
**Post date:** [August 1, 2019, 1:30pm UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/16 "2019-08-01T13:30:51Z")

</div>

```auto
set terminal pngcairo enhanced size 2400,2000

set style fill transparent solid 0.3 noborder
set style circle radius 0.006

plot 'heatmap' u ($1):($2):($3) with circles lc palette

```

0 ft to 5000 ft:

 ![heatmap-0-5000](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/b/d/bd56404f57107293bd26544d9ca18ad661a249d1.png)

5001 ft to 15000 ft:

 ![heatmap-5000-15000](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/8/d/8d2b431a561df3eb0e87bf3d315c09e85191a94d.png)  
15001 ft to 25000 ft:

 ![heatmap-15000-25000](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/a/0/a08d99d9176b9ac2c733930e7c8231938e8557ee.jpeg)

25001 ft to 35000 ft:

 ![heatmap-25000-35000](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/8/1/814bd8acf3f8158fbeb9158ea928b17c4d3ce7ad.jpeg)

35001 ft to 45000 ft:

 ![heatmap-35000-45000](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/3/d/3dff5aee90d6eaac597c7b74703c4f326d1907d4.jpeg)

---

<div class="post-metadata">

**Author:** ![caius](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/caius/32/113839_2.png) [@caius](https://discussions.flightaware.com/u/caius)\
**Post date:** [August 1, 2019, 1:43pm UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/17 "2019-08-01T13:43:44Z")

</div>

Where are you selecting the altitude - Are you filtering the file before, or doing it in gnuplot? I have a version that does it in gnuplot. I’ll post when I get home.

---

<div class="post-metadata">

**Author:** ![wiedehopf](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/wiedehopf/32/114045_2.png) [@wiedehopf](https://discussions.flightaware.com/u/wiedehopf)\
**Post date:** [August 1, 2019, 1:45pm UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/18 "2019-08-01T13:45:44Z")

</div>

> [@caius](#):
>
> I have a version that does it in gnuplot.

That’s probably better, i filtered with jq, but it’s slow to run that multiple times 😉  
Also didn’t fix the plot range so it stays consistent.

(I copied the data over to my laptop, it runs a little faster here, also i don’t want airspy\_adsb to start dropping samples, which it does with heavy memory usage)

---

<div class="post-metadata">

**Author:** ![abcd567](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/abcd567/32/113769_2.png) [@abcd567](https://discussions.flightaware.com/u/abcd567)\
**Post date:** [August 1, 2019, 6:54pm UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/19 "2019-08-01T18:54:20Z")

</div>

### 5-Minutes Run

`nohup ./heatmap.sh 5 10 &`

 ![heatmap-2019-08-01](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/3/e/3eb255a377bab654183319da4f452978d8c75aad.png)

---

<div class="post-metadata">

**Author:** ![caius](https://sea1.discourse-cdn.com/flex019/user_avatar/discussions.flightaware.com/caius/32/113839_2.png) [@caius](https://discussions.flightaware.com/u/caius)\
**Post date:** [August 1, 2019, 7:08pm UTC](https://discussions.flightaware.com/t/signal-strength-heatmap/53109/20 "2019-08-01T19:08:15Z")

</div>

> [@wiedehopf](#):
>
> ```auto
> set style fill transparent solid 0.3 noborder 
> set style circle radius 0.006
> 
> ```

This increases memory usage by gnuplot a considerable amount - when filtering altitude in gnuplot the pi ran out of memory and rebooted. It runs fine on the same data with dots.

I compared filtering in gnuplot and awk, and it’s a bit faster with awk and more convenient, since gnuplot’s conditional plotting is a bit harder to get to do what you want.

I’ve updated the script on github - set the high and low altitude cut off at the top.

 ![image](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/d/b/db19ba6930dc0498c0e04351af35fc23f3d4d750.png)  
 ![image](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/4/2/4236292179ddf746d7c554c4cc5a555f18dbb441.png)  
 ![image](https://us1.discourse-cdn.com/flex019/uploads/flightaware/original/3X/3/3/33e46f85182da64a5269aa1f6179ee4b50c64171.png)

The low altitude one has some spurious data points in it which are a pain to remove. It will be easier to set range to remove those once it’s switched to polar plotting.

[Next page](https://discussions.flightaware.com/t/signal-strength-heatmap/53109.md?page=2)
