# Valid GeoJSON object for choroplethmapbox Trace

**URL:** <https://discourse.julialang.org/t/valid-geojson-object-for-choroplethmapbox-trace/72592>\
**Category:** Geo\
**Created:** [December 4, 2021, 9:34pm UTC](https://discourse.julialang.org/t/valid-geojson-object-for-choroplethmapbox-trace/72592 "2021-12-04T21:34:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dieter](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dieter/32/29860_2.png) [@Dieter](https://discourse.julialang.org/u/Dieter)\
**Post date:** [December 4, 2021, 9:34pm UTC](https://discourse.julialang.org/t/valid-geojson-object-for-choroplethmapbox-trace/72592/1 "2021-12-04T21:34:05Z")

</div>

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](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

```julia
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](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

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

```

or to download via

```julia
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

```julia
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:

```julia
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

---

<div class="post-metadata">

**Author:** ![empet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/empet/32/221303_2.png) [@empet](https://discourse.julialang.org/u/empet)\
**Post date:** [December 5, 2021, 12:29pm UTC](https://discourse.julialang.org/t/valid-geojson-object-for-choroplethmapbox-trace/72592/2 "2021-12-05T12:29:12Z")

</div>

With these lines you’ll get the right choroplethmapbox:

```julia
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`.

 ![Austria](https://global.discourse-cdn.com/julialang/original/3X/5/9/596ca5a6eebe0bd2562109ca1ff23ea26d34a979.jpeg)

---

<div class="post-metadata">

**Author:** ![Dieter](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dieter/32/29860_2.png) [@Dieter](https://discourse.julialang.org/u/Dieter)\
**Post date:** [December 5, 2021, 12:45pm UTC](https://discourse.julialang.org/t/valid-geojson-object-for-choroplethmapbox-trace/72592/3 "2021-12-05T12:45:18Z")

</div>

> [@empet](#):
>
> `url`

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”

---

<div class="post-metadata">

**Author:** ![empet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/empet/32/221303_2.png) [@empet](https://discourse.julialang.org/u/empet)\
**Post date:** [December 5, 2021, 2:04pm UTC](https://discourse.julialang.org/t/valid-geojson-object-for-choroplethmapbox-trace/72592/4 "2021-12-05T14:04:56Z")

</div>

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)

```julia
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"]`

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

```

Add a new property:

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

```

save the modified geojson to a local json file:

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

```

Read the new geojson file:

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

```

Inspect that the new property is present:

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

```

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

---

<div class="post-metadata">

**Author:** ![Dieter](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dieter/32/29860_2.png) [@Dieter](https://discourse.julialang.org/u/Dieter)\
**Post date:** [December 5, 2021, 4:28pm UTC](https://discourse.julialang.org/t/valid-geojson-object-for-choroplethmapbox-trace/72592/5 "2021-12-05T16:28:00Z")

</div>

> [@empet](#):
>
> `newjdata`

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.
