How to change the country name and then draw the global map?

Hi, I got the dataset like following:
image
I want to make a world map and see which country have higher mean salary, maybe represent through density or sth else, like density higher means the mean salary is higher, I tried do that with vegalite but I always got the error:
image
then I realized this data have country name like this:


Ru means russia, NZ means new zealand โ€ฆIs there any way that I can covert these into the complete country name? and where have I got wrong on this map code?
Can someone help me with that please?
Thanks for any help:)

1 Like

You can find a mapping between country codes and country names here List of country codes by alpha-2, alpha-3 code (ISO 3166) (assuming your country codes follow the standard pattern). You can add a column to your data frame using leftjoin to add a column with a full country names based on the on column that are country codes.

2 Likes

Adding to @bkamins 's answer, you can then use the complete country code to download the geometries into a geospatial table:

using GeoTables

BRA = GeoTables.gadm("BRA", depth = 1)

These tables can be plotted directly with either MeshViz.jl (or GeoStatsViz.jl):

using MeshViz

import GLMakie as Mke

viz(BRA, variable=:column_with_color)
5 Likes

Very nice!

2 Likes

For the country lookup part, you can use Countries.jl:

julia> using Countries

julia> get_country("NZ").common_name
"New Zealand"

You can get a dataframe of all countries like so, so that you can use @bkaminsโ€™s suggested join:

julia> using Countries, DataFrames

julia> DataFrame(all_countries())
249ร—7 DataFrame
 Row โ”‚ alpha2  alpha3  name                  numeric  official_name    โ‹ฏ
     โ”‚ String  String  String                Int16    String           โ‹ฏ
โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
   1 โ”‚ AW      ABW     Aruba                     533  Aruba            โ‹ฏ
   2 โ”‚ AF      AFG     Afghanistan                 4  Islamic Republic
   3 โ”‚ AO      AGO     Angola                     24  Republic of Ango
   4 โ”‚ AI      AIA     Anguilla                  660  Anguilla
   5 โ”‚ AX      ALA     ร…land Islands             248  ร…land Islands    โ‹ฏ
  โ‹ฎ  โ”‚   โ‹ฎ       โ‹ฎ              โ‹ฎ               โ‹ฎ                    โ‹ฎ โ‹ฑ
 246 โ”‚ YE      YEM     Yemen                     887  Republic of Yeme
 247 โ”‚ ZA      ZAF     South Africa              710  Republic of Sout
 248 โ”‚ ZM      ZMB     Zambia                    894  Republic of Zamb
 249 โ”‚ ZW      ZWE     Zimbabwe                  716  Republic of Zimb โ‹ฏ
                                          3 columns and 240 rows omitted
4 Likes

Thank you soooooooo much!!! I finally got this out!!!

Hi, Thank you so much for the guide!! but I have met some problem, I got the full data table like this:
image
I have googled gadm it says it loads data from the GADM project, I tried put my data in there but it appeared to be some errors, same error still appear even I make a new dataset contain only the alpha3 column, can you please give me some advices about it?
image

@akshdfyehd you misunderstood the gadm function. You need to pass the name of the country to it. โ€œfinalโ€ is a table.

Try

geotable = GeoTables.gadm("BRA")

and will see a special table object that has a set of attribute columns and a special column called โ€œgeometryโ€. You can access the attribute table with values(geotable) and the underlying geometries with domain(geotable). Watch my JuliaCon talk to understand these concepts:

You can also access the columns of the geotable with familiar syntax like geotable.geometry or geotable.NAME etc. If you want the geometries I recommend using domain(geotable) instead of geotable.geometry because the former is what we call โ€œtype-stableโ€ in Julia.

Please feel free to ask more questions if something is not working or is not clear.

2 Likes

Thank you for that video link and reply!! :laughing:
but my goal is to present the comparison of the salary(which is the โ€˜Meanโ€™ column) by differentiate the densities or colors for different countries and produce a world map, but these functions in the video seems only be able to visualize only one country? Am I right? If my understanding is correct, I need to pass all 50 country code into that function manually and combine and compare them, so can you please tell me an easier way to achieve that? If my understanding is wrong, please give me some advices :grinning:

The GADM dataset is organized on a country level. It is not possible to download the full world map with a single call (it would be a huge dataset going all the way down to states, counties, etc.).

The simplest method to produce a world map with a given collection of countries is the following. Suppose you have a vector with country codes:

countries = ["BRA", "ARG", "PER"]

You can download the geotables for these specific countries with:

geotables = [GeoTables.gadm(country, depth=0) for country in countries]

Notice the option depth=0. It is used to download the geometry of the country itself instead of the geometries of the states and counties inside the country. You can pass depth=0,1,2,.. all the way down to zoom into specific polygons.

After you have the geospatial tables, you can then extract the polygon of the country for plotting:

polygons = [first(geotable.geometry) for geotable in geotables]

Plotting a vector of polygons is super easy:

using MeshViz

import GLMakie as Mke

viz(polygons)

You can pass a vector of colors and transparencies with the options color and alpha:

viz(polygons, color = 1:3)

and pick any color scheme from the ColorSchemes.jl package:

viz(polygons, color = 1:3, colorscheme = :tab10)

Let me know if something is not clear. We designed an ecosystem for geospatial data in GeoStats.jl that is very intuitive for first-time users. Everything should work as you would expect.

3 Likes

Another issue with using GDAM for global maps, other than having to make a collection from individual countries, is that the country polygons have a too high resolution. Itโ€™s simpler to use a low resolution dataset, like for example geo-countries/countries.geojson at master ยท datasets/geo-countries ยท GitHub

I have updated the GMT.jl choropleth examples where one does something very similar to what the OP seems to want. Adapting this example to the Mean salary data should be straightforward.

Using GMT, CSV, HTTP, DataFrames

# Read the country polygons directly into a GMTdadset
countries = gmtread("/vsicurl/https://github.com/datasets/geo-countries/raw/master/data/countries.geojson");

# Read a file with the population density into a DataFrame
pop = CSV.File(HTTP.get(https://raw.githubusercontent.com/tillnagel/unfolding/master/data/data/countries-population-density.csv).body, delim=';') |> DataFrame;

Both the countries and pop share a common attribute, the Country code

julia> countries
Vector{GMTdataset} with 4264 segments
Show first segment. To see other segments just type its element number. E.g. D[7]

Attributes:  Dict("ISO_A2" => "AW", "ISO_A3" => "ABW", "ADMIN" => "Aruba")
BoundingBox: [-70.06240800699987, -69.87682044199994, 12.417669989000046, 12.632147528000104]
PROJ: +proj=longlat +datum=WGS84 +no_defs

and

julia> pop
248ร—3 DataFrame
 Row โ”‚ Country Name                       Country Code  2010
     โ”‚ String                             String3       Float64?
โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
   1 โ”‚ Arab World                         ARB            26.2725
   2 โ”‚ Caribbean small states             CSS            16.9939
   3 โ”‚ East Asia & Pacific (all income โ€ฆ  EAS            90.5122
   4 โ”‚ East Asia & Pacific (developing โ€ฆ  EAP           123.729

Now create a numeric vector linking the population density and the country polygons via the attribute โ€œISO_A3โ€

zvals = polygonlevels(countries, string.(pop[!,2]), pop[!,3], att="ISO_A3");

and use it to create the colors in the map.

# First create the colormap. Limit the maximum range to 500 otherwise states
# like Monaco would the all the `reds` and the rest of the world would be all blues.
C = makecpt(range=(0,500,10));
plot(countries, region=(-180,180,-60,85), level=zvals, cmap=C, proj=:guess,
     title="World population density", colorbar=true, show=true)

2 Likes

That is why GeoTables.jl downloads the GADM data and performs decimation of the polygons behind the scenes for the end-user:

help?> GeoTables.gadm
  gadm(country, subregions...; depth=0, decimation=0.04)


  (Down)load GADM table using GADM.get and convert the geometry column to Meshes.jl geometries.

  The depth option can be used to return tables for subregions at a given depth starting from the given region specification.

  If decimation is greater than zero, decimate the geometries to reduce the number of vertices. The greater is the decimation value, the more aggressive is the
  reduction.
2 Likes

Thanks for the reply!! I have take the top5 countries:
image
I was follow the code you have showed, they all goes well until the last step in viz, after I press enter I thought there should be a web pop out with the graphs, but it just stays like this for about an hour (its not crash), I have tried restart julia and repeat the process but nothing change, was it supposed to be wait for long time or something goes wrong?


Thanks for the help!!! I really appreciate it!!!

Can you please confirm the versions of the packages you have installed?

Type the following:

] status

If you are using an old version of GeoTables.jl (<1.0.3), you may need to explicitly use the option decimation explained above to reduce the number of vertices in the polygons. You can seee that they currently have 5703, 8437 and 1670 that need to be triangulated in the visualization.

Another issue is that GLMakie.jl itself is slow to compile. So assuming you solved the issue above regarding decimation, you can see if the plot shows up. For me it shows in a few seconds.

1 Like

@akshdfyehd you can first try to reproduce my example with the countries I tried. If it works, then you are in the right path. The countries you chose like Russia, are very big geographically, so the number of points needed to represent them in detail is large. You may need to specify a more aggressive decimation option.

1 Like

Sorry, a correction here. These number refer to the sub-polygons of the polygon loaded.

If you are having trouble with the GADM data set, try to use any other geojson file with countries that you can find online like the one others shared above. You can use GeoTables.load("foo.geojson") to load it in the same format.

1 Like

Hi,
I got the countries like this:
image
and I got the dataframe like this:
image
for the next step which is zval using polygonlevels, my result comes out like this:
image
its all NA values returned, Do you know what caused this? really appreciate any advices!!!

Hmm, a few things.

  • First just a side note. Itโ€™s easier to read if you paste plain text, wrapped under triple back ticks, then screen-shots.
  • In you case you donโ€™t need to use string.(final[!,2]) because your second column is already a string (that was not the case in my example)
  • I have fixed the above and several other cases in the GMT.jl master version. Unfortunately Iโ€™m very limited to release new GMT.jl versions due to a Julia libs dependency conflict.

I assume that your dataset is a public one, so the best is that you show us (or just me) a download link so I can debug why is polygonlevels failing to cross-link both data and return only NaNs.

1 Like

Hi, this is the link:
https://raw.githubusercontent.com/akshdfyehd/salary/main/ds_salaries.csv

Thanks!!!

Hey, I have found the solution, which comes from my tutor:
This is the final data:
image
code is like this:
image
image
and get the result like this:
image