Plotting data on a map using the Google Map API

In this recipe, we will diverge from the desktop environment and show how we can output for the Web. Although the main language for the web frontend is not Python but HTML, CSS, and JavaScript, we can still use Python for heavy lifting: fetch data, process it, perform intensive computations, and render data in a format(s) suitable for web output, that is, create HTML pages with the required JavaScript version to render our visualization(s).

Getting ready

We will use Google Data Visualization Library for Python to help us prepare data for the frontend interface, where we will use another Google Visualization API to render data in the desired visualization, that is, a map and a table.

Before we start, we need to install the google-visualization-python module. Download the latest stable version from Github and install the module. The following actions demonstrate how to do this:

$ git clone https://github.com/google/google-visualization-python.git

$ cd google-visualization-python/

$ sudo python setup.py install

Note that we have to become a super user (that is, gain administrator privileges) to install this module on our system.

A better option, if you don't want to pollute your OS packages, is to create a virtualenv environment to install the packages just for this recipe. We explained how to deal with virutalenv environments in Chapter 1, Preparing Your Working Environment.

For the frontend library we don't have to install anything, as that library will be loaded from the web page directly from the Google servers.

We need active access to the Internet for this recipe, because the output of it will be a web page that will, when opened in a web browser, pull the JavaScript libraries directly from remote servers.

In this recipe, you will learn how to use Google Data Visualization Library for Python and JavaScript to combine them for creating web visualization.

How to do it...

The following example shows how to visualize Disposable Median Monthly Salary per Country on the world map projection using Google Geochart and Table Visualization, loading the data from a .csv file using Python and the gdata_viz module. We will:

  1. Implement a function to act as a template generator.
  2. Use the csv module to load the data from the local .csv file.
  3. Use DataTable to describe the data and LoadData to load the data from the Python dictionary.
  4. Render the output to a web page.

This can be achieved with the following code:

import csv
import gviz_api

def get_page_template():
    page_template = """
    <html>
      <script src="https://www.google.com/jsapi" type="text/javascript"></script>
      <script>
        google.load('visualization', '1', {packages:['geochart', 'table']});

        google.setOnLoadCallback(drawMap);
        function drawMap() {
            var json_data = new google.visualization.DataTable(%s, 0.6);
            
            var options = {colorAxis: {colors: ['#eee', 'green']}};
            var mymap = new google.visualization.GeoChart(
                                document.getElementById('map_div'));
            mymap.draw(json_data, options);
            
            var mytable = new google.visualization.Table(
                                document.getElementById('table_div'));
            mytable.draw(json_data, {showRowNumber: true})
        }
      </script>
      <body>
        <H1>Median Monthly Disposable Salary World Countries</H1>

        <div id="map_div"></div>
        <hr />
        <div id="table_div"></div>

        <div id="source">
        <hr />
        <small>
        Source: 
        <a href="http://www.numbeo.com/cost-of-living/prices_by_country.jsp?displayCurrency=EUR&itemId=105">
        http://www.numbeo.com/cost-of-living/prices_by_country.jsp?displayCurrency=EUR&itemId=105
        </a>
        </small>
        </div>
      </body>
    </html>
    """
    return page_template
def main():
    # Load data from CVS file
    afile = "median-dpi-countries.csv"
    datarows = []
    with open(afile, 'r') as f:
        reader = csv.reader(f)
        reader.next()  # skip header
        for row in reader:
            datarows.append(row)

    # Describe data
    description = {"country": ("string", "Country"),
                       "dpi": ("number", "EUR"), }

    # Build list of dictionaries from loaded data
    data = []
    for each in datarows:
        data.append({"country": each[0],
                     "dpi": (float(each[1]), each[1])})

    # Instantiate DataTable with structure defined in 'description'
    data_table = gviz_api.DataTable(description)

    # Load it into gviz_api.DataTable
    data_table.LoadData(data)

    # Creating a JSon string
    json = data_table.ToJSon(columns_order=("country", "dpi"),
                             order_by="country", )
    
    # Put JSON string into the template
    # and save to output.html
    with open('output.html', 'w') as out:
        out.write(get_page_template() % (json,))

if __name__ == '__main__':
    main()

This will produce the output.html file, which we can open in our favorite web browser. The page should look like the following screenshot:

How to do it...

How it works...

The main entry point here is our main() function. First, we use the csv module to load our data. This data is obtained from the public website www.numbeo.com, and the data is put in the .csv format. The final file is available in the repository for this chapter in the Chapter06 folder. To be able to use Google Data Visualization Library, we need to describe the data to it. We describe data using the Python dictionaries, where we define the ID of the columns, their data type, and an optional label. In the following example, the data is defined in this constraint:

{"name": ("data_type", "Label")}:
description = {"country": ("string", "Country"),
                       "dpi": ("number", "EUR"), }

Then we need to fit our loaded .csv rows in this format. We will build a list of dictionaries in the data variable.

Now we have everything to instantiate our data_table with gviz_data.DataTable with the described structure. We then load the data into it and output in the JSON format to our page_template.

The get_page_template() function contains the other part of this equation. It contains a client (frontend) code to produce an HTML web page and a JavaScript code to load Google Data Visualization Library from Google servers. The line that loads the Google JavaScript API is:

<script src="https://www.google.com/jsapi" type="text/javascript"></script>

After this follows another pair of <script>...</script> tags that contains an additional setup. First, we load Google Data Visualization Library and the required package—geochart and table:

google.load('visualization', '1', {packages:['geochart', 'table']});

Then we set up a function that will be called when the pages are loaded. This event in the web world is registered as onLoad, so callback is set up via setOnLoadCallback function:

google.setOnLoadCallback(drawMap);

This defines that when a page is loaded, the Google instance will call the custom function drawMap() that we defined. The drawMap function loads a JSON string into the JavaScript version of the DataTable instance:

var json_data = new google.visualization.DataTable(%s, 0.6);

Following that, we create a geochart instance in an HTML element with the ID map_div:

var mymap = new google.visualization.GeoChart(
document.getElementById('map_div'));

Draw the map using json_data and provided custom options:

mymap.draw(json_data, options);

Similarly, Google's JavaScript table is rendered below the map:

var mytable = new google.visualization.Table(
document.getElementById('table_div'));
mytable.draw(json_data, {showRowNumber: true})

We save this output as an HTML file that we can open in a browser. This is not so useful for the dynamic rendering of a web service. There is a better option for this—to output the HTTP response directly from Python, and thus build a background service responding to client web requests with JSON that a client can load and render.

Note

If you want to understand more on reading HTTP responses, please read more on HTTP Protocol and Response messages at http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Response_message.

We do this by replacing the ToJson() call with the ToJSonResponse() with the same signature. This call will respond with a proper HTTP response containing the payload—our JSON-ified data_table ready to be consumed by our JavaScript client.

There's more...

This, of course, is just one example of how we can combine Python as a backend language, sitting on our server, doing the data fetch and processing, while the frontend is left to the universal HTML/JavaScript/CSS set of languages. This enables us to provide interactive and dynamic interfaces with visualizations to a wide audience without requiring them to install anything (well, apart from a web browser, but that is usually installed on a computer or smartphone). Saying that, we must note that the quality of these outputs is not as high as that of matplotlib; the strength of matplotlib lies in its high-quality output.

To work more with the web (and Python), you would have to learn more about the web technologies and languages used. This book does not cover such topics but does give an insight into how to achieve one possible solution using well-known third-party libraries that produce pleasing web outputs, with as little web coding as possible.

Tip

More documentation is available on the Google Developer portal at https://developers.google.com/chart/interactive/docs/dev/gviz_api_lib.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.209.180