Plot the geographical coordinates of IPs (v4) using a database (CSV) in a world map image using the Mercator projection.
- Version: 1.2.2 (2025-09-23)
- Requires:
matplotlib,netaddr.
Many Linux distributions already have a package manager that allows to download this dependencies:
-
Debian:
$ sudo apt-get install python3-matplotlib $ sudo apt-get install python3-netaddr -
Gentoo:
$ sudo emerge -a matplotlib $ sudo emerge -a netaddr -
Arch Linux:
$ sudo pacman -S python-matplotlib $ sudo pacman -S python-netaddr
If that's not the case, you can always install those packages by using the pipx tool:
$ pipx install matplotlib $ pipx install netaddr All needed data could be conveniently contained in the folder data/, although through arguments you can specify another files or path. The usage of the main entry is:
-h, --help show this help message and exit -i, --iplist IPLIST file of IPs to plot, one per line -g, --geodb GEODB CSV document with columns: 'network,lat,lon' -f, --imagefile IMAGEFILE path for the template image to plot over -W, --width WIDTH width in pixels of the image file -H, --height HEIGHT height in pixels of the image file -l, --left LEFT degrees most to the left in the image -r, --right RIGHT degrees most to the right in the image -b, --bottom BOTTOM degrees most to the bottom in the image -n, --nsplits NSPLITS parts in which the file 'geodb' is divided (threading) -w, --nworkers NWORKERS set number of workers (multiprocessing) -v, --verbose verbose messages on each action You can see this options anytime by using the -h or --help argument. The default values for the options -l, -r, and -b are calibrated for the Mercator map with resolution of 2058×1746 pixels you can find in Wikipedia, as explained below.
Three files are required for this program to work:
-
Image file. This is a world map image in the Mercator projection. The file properties such as
width,length, and the degrees of left, right, and bottom boundaries depicted may be entered through the command line, as well as the filename. When changing the image, you have to adjust three points specified in degrees, the point most to the left (by default is -180°), the point most to the right (by default is 180°), and the point most to the south. It shouldn't be greater than -90°, although if you have a map where the most fore south point is exactly at -90°, you should use an approximation, such as -89.99, or a division by zero may happen because the linear scale becomes infinitely large at the poles in this projection.The default map for the configured settings is the one you can find in Wikipedia for the article: "Mercator Projection", but in the size of 2058×1746 pixels. It's set between 82°S and 82°N, i.e., with latitudes in the range [-82, 82].
You can download and use a different map, or the same map in a different resolution, but you'll have to specify the dimensions and other parameters through the command line when invoking the program.
-
IP list. A file of the IPs you want to plot in a map. There have to be IP addresses, not in subnet notation or netmasks, one per line. By default, the file used will be
data/ips.lst. For example:... 77.247.181.162 198.98.56.149 185.220.100.252 162.247.74.202 195.176.3.19 145.239.91.37 185.220.101.54 51.15.125.181 ... -
Geocoordinates database. A CSV file containing the following columns, without comments (may be this will be solved in a future version):
netmask, latitude, longitude. The default CSV file used isdata/geoip_ipv4.csv. For example:... 73.185.104.0/23,37.8209,-121.2827 73.185.106.0/23,38.6106,-121.2789 73.185.108.0/23,38.5879,-121.4053 73.185.110.0/23,38.6711,-121.1495 73.185.112.0/23,36.3170,-119.3087 73.185.114.0/23,38.1345,-120.4516 73.185.116.0/23,39.1663,-121.5105 ...
-
Download the Mercator map (2058×1746 pixels) from Wikipedia: https://upload.wikimedia.org/wikipedia/commons/f/f4/Mercator_projection_SW.jpg and save it in the
datafolder under the name ofworldmap_raw.jpg. -
Put a file containing the IPs you want to plot (one per line) in the map in the folder
dataunder the name ofips.lst. -
Create a CSV database with the columns:
netmask,latitude,longitudeand save it in the folderdataunder the namegeoip_ipv4.csv. See below.
The CSV database of 'network, longitude, latitude' is not included due its weight, but it can be constructed easily.
-
Download as a test the GeoLite2 City database in CSV format. You'll find it at: https://archive.org/download/geo-lite-2-city-csv-20210713/GeoLite2-City-CSV_20210713.zip.
-
Uncompress that file and work with the
GeoLite2-City-Blocks-IPv4.csvfile. It's a very huge file and has much more information that the needed for this program to run. -
Create a new document using the following command:
$ awk -F',' '{print $1","$8","$9}' GeoLite2-City-Blocks-IPv4.csv >geoip_ipv4.csvPut the output file in the
datadirectory with the namegeoip_ipv4.csv.
The only requirement is the format of the files and the projection used in the map. You can use different filenames specifying them in the option arguments:
Instead python main.py, you may use:
$ python main.py -i <my_iplist> -g <my_geodb> -f <my_image> -b -80 When changing the image, you have to specify, at least, the degrees more to the south the map displays (and in some cases, the points more to the west and/or to the right when the map is not calibrated in between 180°W and 180°E, i.e., the range [-180, 180], for degrees of longitude.
This is an example of the output provided by this program using matplotlib. This image is a zoomed detail.
The red dots indicate each one of the locations of the IPs in the file ips.lst. The radius of this circle is calculated automatically in the function plot_pixels (in the geoipmap.py file).
The automatic calculation provides a way to draw the circles with a size in relation to the image size. The computation is performed by getting the biggest dimension of the image, and set the radius to a 0.3% of this length, so, for the most common resolutions:
| Resolution | Radius |
|---|---|
| 800×600 | 2.400 |
| 1024×768 | 3.072 |
| 1280×1024 | 3.840 |
| 1920×1080 | 5.760 |
| 3840×2160 | 11.520 |
| 7680×4320 | 23.040 |
The default image detailed above has a resolution of 2058×1746 pixels, so its radius will be 6.174 pixels.
This default behaviour can be altered by invoking the plot_pixels function with an extra argument indicating the float value of the radius in pixels.
# Automatic radius geo.plot() # User defined radius geo.plot(radius=10) This function is invoked in the main entry, at the end of the file main.py.
Copyright (c) 2019-2025, J. A. Corbal Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. A simple permissive license with conditions only requiring preservation of copyright and license notices. Licensed works, modifications, and larger works may be distributed under different terms and without source code. Read the LICENSE file).
Under this license, you may:
- use the software for commercial use;
- modify the software and create derivatives;
- distribute original or modified works;
- place warranty on the software licensed.
With:
- this license includes a limitation of liability
- this software does NOT provide any warranty
More information about the license: https://opensource.org/license/MIT
Copyright (c) 2019-2025, J. A. Corbal
