Altair: add documentation how to load a local topojson file

Created on 31 Jan 2019  路  12Comments  路  Source: altair-viz/altair

is this pseudo code supported

import pandas as pd
import altair as alt

counties = alt.topo_feature('https://raw.githubusercontent.com/djouallah/R_leaflet_MAP/master/foundation.json', 'id')

map =alt.Chart(counties).mark_geoshape().encode(
    color='id:Q'
                                                 )
map

all the documentation is using "data.world_110m.url", how about local topojson or geojson files ?

Most helpful comment

I know some of TopoJSON, as 'm working on a Python package regarding this extension of GeoJSON (
https://github.com/mattijn/topojson)*. Its work in progress. but potentially to be used as an interchange format between geographical packages in the Python ecosystem (eg. geopandas and altair).

Without explaining the format, you are dealing with nested objects. So in the alt.topo_feature(url, feature) you have to define the feature or layer that is present within the objects in your TopoJSON file.

This layer or feature (in your case named foundation) contains often multiple geometries, where each geometry refers to certain top-level stored geometric segments or so-called arcs. Next to the geometry, you have to store some attributes of that geometry, which is stored in another nested object properties.

So in order to access these attribute information you have to add properties to enter this nested object.

{
  "type": "Topology",
  "arcs": [[[641, 1092], [0, 116], [89, 0], [0, -116], [-89, 0]]],
  "objects": {
    "foundation": {
      "type": "GeometryCollection",
      "geometries": [
        {
          "arcs": [[0]],
          "type": "Polygon",
          "properties": {
            "id": 22,
            "width": 0.000558,
            "height": 0.000719,
            "area": 0,
            "perimeter": 0.002555,
            "type": "foundation"
          }
        }
      ]
    }
  }
}

Your issue have been discussed before on the Vega-repo: https://github.com/vega/vega/issues/1319
And more work has also been done in: https://iliatimofeev.github.io/gpdvega/

All 12 comments

The file needs to be accessible via HTTP from the renderer. In Juypyter notebook, for example, you can put the file in the same directory as the notebook and then pass the filename to alt.topo_feature.

I tried this , but not working, I save the json file in the same directory

import pandas as pd
import altair as alt

counties = alt.topo_feature('foundation.json', 'id')

map =alt.Chart(counties).mark_geoshape().encode(
    color='id:Q'
                                                 )
map

What frontend are you using? This won't work, for example, in Binder, but it will work in a local JupyterLab frontend.

I am using a local jupyter lab, and it produces empty chart

Does it work if you use a local data file for a basic dataset? i.e. this works for me in a local JupyterLab:

import altair as alt
from vega_datasets import data

cars = data.cars()
filename = 'cars.json'
cars.to_json(filename, orient='records')

alt.Chart(filename).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color='Origin:N'
)

yes that code works

In that case, I suspect the issue is your topojson file is not correctly formatted.

To be honest, I don't know much about topojson and have not used this part of the library, so I'm not going to be much help in debugging it. I'd start by comparing the format of your topojson file with the files used in the examples, and see if there are any glaring inconsistencies.

If you figure anything out and would like to add hints to the documentation, that would be greatly appreciated.

yeah, I found the issue, the second argument in alt.topo_feature has to be the name of the objects not the id, in the attached example _"objects":{"foundation":{_

import altair as alt
floor_Plan = alt.topo_feature('https://raw.githubusercontent.com/djouallah/R_leaflet_MAP/master/foundation.json', 'foundation')
alt.Chart(floor_Plan).mark_geoshape().encode(
color='properties.id:N',
tooltip=['properties.id:N'])

for some reason, we need to add "properties" to the field name ?

thanks for the help

I know some of TopoJSON, as 'm working on a Python package regarding this extension of GeoJSON (
https://github.com/mattijn/topojson)*. Its work in progress. but potentially to be used as an interchange format between geographical packages in the Python ecosystem (eg. geopandas and altair).

Without explaining the format, you are dealing with nested objects. So in the alt.topo_feature(url, feature) you have to define the feature or layer that is present within the objects in your TopoJSON file.

This layer or feature (in your case named foundation) contains often multiple geometries, where each geometry refers to certain top-level stored geometric segments or so-called arcs. Next to the geometry, you have to store some attributes of that geometry, which is stored in another nested object properties.

So in order to access these attribute information you have to add properties to enter this nested object.

{
  "type": "Topology",
  "arcs": [[[641, 1092], [0, 116], [89, 0], [0, -116], [-89, 0]]],
  "objects": {
    "foundation": {
      "type": "GeometryCollection",
      "geometries": [
        {
          "arcs": [[0]],
          "type": "Polygon",
          "properties": {
            "id": 22,
            "width": 0.000558,
            "height": 0.000719,
            "area": 0,
            "perimeter": 0.002555,
            "type": "foundation"
          }
        }
      ]
    }
  }
}

Your issue have been discussed before on the Vega-repo: https://github.com/vega/vega/issues/1319
And more work has also been done in: https://iliatimofeev.github.io/gpdvega/

@mattijn thanks for the explanation, I appreciate if you have a look at https://github.com/altair-viz/altair/issues/1322

Dear future reader:

  • if you use Jupyter Notebook
  • if you try to load data from a non-HTTPS url but HTTP

This will fail due to CORS for reasons I cannot imagine.
There will be no warnings nor errors messages visibly shown anywhere (unless you consider the browser console as a valid place to look at).
You will just get a blank chart.

So, make sure you check the browser console when you do anything in Altair in Jupyter Notebook and make sure you do not run into CORS errors.

@djouallah your problem literally solved my problem.I wanted to plot for the country India...It is sorted now

`
import altair as alt

url = "https://raw.githubusercontent.com/deldersveld/topojson/master/countries/india/india-states.json"

source = alt.topo_feature(url, "IND_adm1")

alt.Chart(source).mark_geoshape().encode(
tooltip='properties.NAME_1:N'
)
`

Was this page helpful?
0 / 5 - 0 ratings

Related issues

maxgerma picture maxgerma  路  3Comments

fischcheng picture fischcheng  路  4Comments

zanarmstrong picture zanarmstrong  路  4Comments

nielsmde picture nielsmde  路  4Comments

DentonGentry picture DentonGentry  路  3Comments