Valid GeoJSON object for choroplethmapbox Trace

Hello Community!

I try to create a plotly choroplethmapbox using a GeoJSON for the coordinates of the geographical regions and a dataframe containing the values which are used to color the regions.

Plotly choroplethmapbox accepts according to https://plotly.com/julia/reference/choroplethmapbox/#choroplethmapbox-geojson for the attribute geojson an URL containing a geojson or a valid GeoJSON object

While using a URL for the geojson is working fine

q=PlotlyJS.plot(PlotlyJS.choroplethmapbox(df,geojson = "https://raw.githubusercontent.com/ginseng666/GeoJSON-TopoJSON-Austria/master/2016/simplified-95/laender_95_geo.json",locationmode = "geojson-id",featureidkey = "properties.iso",locations = df.iso,z=df.Wert,text=df.names,colorscale="Viridis",zmin=0,zmax=1,marker=attr(opacity=0.5,line=attr(width=0.1,color="white"))),PlotlyJS.Layout(mapbox =attr(center=attr(lon =12,lat=48),zoom=6,style="open-street-map")))

it was not possible to create the valid GeoJSON object based on the content from https://raw.githubusercontent.com/ginseng666/GeoJSON-TopoJSON-Austria/master/2017/simplified-99.9/laender_999_geo.json

I tried to download the file and to use

A=GeoJSON.read(read("/home_local/dmayer/Downloads/AT_Laender.geojson"))

or to download via

resp = HTTP.get("https://raw.githubusercontent.com/ginseng666/GeoJSON-TopoJSON-Austria/master/2016/simplified-95/laender_95_geo.json")
str = String(resp.body)
A = GeoJSON.read(str)

and then

q=PlotlyJS.plot(PlotlyJS.choroplethmapbox(df,geojson = A,locationmode = "geojson-id",featureidkey = "properties.iso",locations = df.iso,z=df.Wert,text=df.names,colorscale="Viridis",zmin=0,zmax=1,marker=attr(opacity=0.5,line=attr(width=0.1,color="white"))),PlotlyJS.Layout(mapbox =attr(center=attr(lon =12,lat=48),zoom=6,style="open-street-map")))

but this was without success. How could be a valid GeoJSON object been created from the URL or from the downloaded content?

In order to make this example reproducable, the used dataframe df was created by:

df = DataFrame(iso=["8","7","9","2","1","4","3","6","5"], names=["Vorarlberg", "Tirol", "Wien", "Kärnten","Burgenland","Oberösterreich","Niederösterreich","Steiermark","Salzburg"],Wert=[0.1,0.4,0.2,0.5,0.9,0.5,0.7,0.4,0.2])

Thanks for your help, Dieter

With these lines you’ll get the right choroplethmapbox:

url="https://raw.githubusercontent.com/ginseng666/GeoJSON-TopoJSON-Austria/master/2016/simplified-95/laender_95_geo.json"
                                
q = Plot(choroplethmapbox(geojson = url,
                          featureidkey = "properties.iso",
                          locations = df.iso,
                          z=df.Wert,
                          zmin=0, zmax=1, 
                          text=df.names,colorscale="Viridis",
                          marker=attr(opacity=0.85, line=attr(width=0.5, color="white"))),
          Layout(mapbox =attr(center=attr(lon =13.5, lat=47.65),
                                            zoom=5.75, style="open-street-map")))

The data frame, df, must be read before, but not passed simply, as df, to the choroplethmapbox definition. Only its columns are used to set locations, z and text.

1 Like

Thank you for your input!

My example worked when using the geojson as URL, the dataframe df was not the problem.
The initial question was, how a downloaded geojson file (which I could eventually modifiy) could be used.
I want to replace “geojson = url” by geojson = “geojson_object_from_file”

Unfortunately PlotlyJS.jl doesn’t check whether a key/attribute is needed for a trace type. That’s why it worked with df, too.

You can read a geojson file as a json file, and modify some values or add new (key, values)

using JSON, HTTP
url  = "https://raw.githubusercontent.com/ginseng666/GeoJSON-TopoJSON-Austria/master/2017/simplified-99.9/laender_999_geo.json"
result = HTTP.request("GET", url)
jsondata = JSON.parse(String(result.body))

Let us inspect jsondata["features"][1]["properties"]

print(jsondata["features"][1]["properties"])

Add a new property:

for (k, feat) in enumerate(jsondata["features"])
    feat["properties"]["id"]=k
end  

save the modified geojson to a local json file:

stringdata = JSON.json(jsondata)
open("newjson.json", "w") do f
        write(f, stringdata)
end

Read the new geojson file:

newjdata= JSON.parsefile("newjson.json")

Inspect that the new property is present:

for feat in newjdata["features"]
    print(feat["properties"], "\n")
end 

now in the definition of the choroplethmapbox, set geojson=newjdata, instead of geojson=url.

1 Like

Thanks Empet!

Your solution works perfectly. I have just to use JSON.parse(String(result.body)) instead of GeoJSON.read(String(resp.body)), this makes the decisive difference.