This program plots the geographical coordinates of IPs (v4) using a database (CSV) in a world map 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
data
folder 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
data
under the name ofips.lst
. -
Create a CSV database with the columns:
netmask,latitude,longitude
and save it in the folderdata
under 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.csv
file. 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.csv
Put the output file in the
data
directory 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
J. A. Corbal, 2019-2025.