# Climatic variables spatial plotting

Open you preferable Python IDE or Python console and initially import the required libraries. This example is quite more complex than the previous example [Simple climatic variables plotting](/coding-examples/simple-climatic-variables-plotting.md). Beside the standard libraries also imported in the previous example, we are going to need a couple of geospatial related libraries to better handle coordinates.

{% code overflow="wrap" lineNumbers="true" %}

```python
import requests
import json
import numpy as np
import geopandas as gpd
import matplotlib.pyplot as plt
import shapely.geometry
```

{% endcode %}

After importing the libraries, we define all the needed variables to proceed. **Email**, **password**, **climatic*****\_variable*****\_1** and **coordinates** are the essential variables needed to get your responses from the API. The input coordinates of the API are single points, i.e. to time a call is made on the API it refers to specific location requested. Thus to have a collection of spatially distributed points, multiple requests are needed.

{% hint style="info" %}
It's a good idea to bring all variables that you are going to use up, in order to avoid "hard coding" values later in the code
{% endhint %}

{% code overflow="wrap" lineNumbers="true" %}

```python
# Define the user credentials
email = 'YOUR ACCOUNT EMAIL'
password = 'YOUR PASSWORD'
# Define the climatic variable to plot
climatic_variable_1 = 'a-frost-days'  # Average Frost Days
# Define the coordinates of the polygon
lat_point_list = [50.854457, 52.518172, 50.072651, 48.853033, 50.854457]
lon_point_list = [4.377184, 13.407759, 14.435935, 2.349553, 4.377184]
# Create a geopandas structure with the coordinates
polygon_geom = shapely.geometry.Polygon(zip(lon_point_list, lat_point_list))
gdf = gpd.GeoDataFrame(index=[0], crs='epsg:4326', geometry=[polygon_geom])
# total area for the grid
xmin, ymin, xmax, ymax= gdf.total_bounds
# Define the grid
n_cells=5
cell_size = (xmax-xmin)/n_cells
# Projection of the grid
crs = "+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs"
```

{% endcode %}

So far, the **polygon**, **bounding box** and **projection** are defined. Following a **grid** is defined within this polygon. This grid contains the point coordinates to be used in the API calls

{% code overflow="wrap" lineNumbers="true" %}

```python
# Create the cells in a loop
grid_cells = []
for x0 in np.arange(xmin, xmax+cell_size, cell_size):
    for y0 in np.arange(ymin, ymax+cell_size, cell_size):
        # bounds
        x1 = x0-cell_size
        y1 = y0+cell_size
        grid_cells.append(shapely.geometry.box(x0, y0, x1, y1))
cell = gpd.GeoDataFrame(grid_cells, columns=['geometry'], crs=crs)
lng = cell.centroid.x
lat = cell.centroid.y
```

{% endcode %}

Following the process, the user needs to generate the temporally authkey to interact with the rest endpoints.

{% code overflow="wrap" lineNumbers="true" %}

```python
# Step 1: Generate a temporal API key to authentic the other API endpoints
headers = {
    'accept': 'application/json',
    # Already added when you pass json= but not when you pass data=
    # 'Content-Type': 'application/json',
}
json_data = {
    'email': email,
    'password': password,
}
# This the variable that holds the temporally API key
auth_response = requests.post('https://api.answr.space/api:auth/auth/login', headers=headers, json=json_data)
```

{% endcode %}

A for loop is used to loop over all points, make the calls to the API and store the responses into a list.

{% code overflow="wrap" lineNumbers="true" %}

```python
authkey = json.loads(auth_response.content)
for i in range(len(cell)):
    # Step 2: Loop over the points and get the data from the answr.space API
    headers = {
        'accept': 'application/json',
        'Authorization': 'Bearer ' + authkey['authToken'] + '',
    }
    params = {
        'Input_point': '{"type":"point","data":{"lng":' + str(lng[i]) + ',"lat":' + str(lat[i]) + '}}',
    }
    response_1 = requests.get('https://api.answr.space/api:climate-variables/' + climatic_variable_1 + '', params=params,headers=headers)
    # Convert byte responses to json format
    climatic_variable_response = json.loads(response_1.content)
    if response_1.content != b'null':
        # Rename json to key to months for better plot visualization. You can find the response keys in the API reference documentation for each endpoint
        new_key = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
        old_key = {"CV76_M1", "CV76_M2", "CV76_M3", "CV76_M4", "CV76_M5", "CV76_M6", "CV76_M7", "CV76_M8", "CV76_M9", "CV76_M10", "CV76_M11", "CV76_M12"}
        responses.append(dict(zip(new_key, list(climatic_variable_response.values()))))
    else:
        responses.append(dict(zip(new_key, [0]*12)))
```

{% endcode %}

Finally, we can plot the points to spatially understand the variation of the climate statistics.

{% code overflow="wrap" lineNumbers="true" %}

```python
df_responses = pd.DataFrame(responses)
plt.scatter(lng, lat, c = df_responses['March'], cmap= 'viridis')
```

{% endcode %}

<figure><img src="/files/DeCLxOG0osgI8MIH2yKe" alt=""><figcaption></figcaption></figure>

In case you want to run the entire process with a single command, bellow you can find the entire code.

{% code overflow="wrap" lineNumbers="true" %}

```python
import requests
import json
import numpy as np
import geopandas as gpd
import matplotlib.pyplot as plt
import shapely.geometry
import pandas as pd

# Define the user credentials
email = 'YOUR ACCOUNT EMAIL'
password = 'YOUR PASSWORD'
# Define the climatic variable to plot
climatic_variable_1 = 'a-frost-days'  # Average Frost Days
# Define the coordinates of the polygon
lat_point_list = [50.854457, 52.518172, 50.072651, 48.853033, 50.854457]
lon_point_list = [4.377184, 13.407759, 14.435935, 2.349553, 4.377184]
# Create a geopandas structure with the coordinates
polygon_geom = shapely.geometry.Polygon(zip(lon_point_list, lat_point_list))
gdf = gpd.GeoDataFrame(index=[0], crs='epsg:4326', geometry=[polygon_geom])
# total area for the grid
xmin, ymin, xmax, ymax= gdf.total_bounds
# Define the grid
n_cells=5
cell_size = (xmax-xmin)/n_cells
# Projection of the grid
crs = "+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs"
# Create the cells in a loop
grid_cells = []
for x0 in np.arange(xmin, xmax+cell_size, cell_size):
    for y0 in np.arange(ymin, ymax+cell_size, cell_size):
        # bounds
        x1 = x0-cell_size
        y1 = y0+cell_size
        grid_cells.append(shapely.geometry.box(x0, y0, x1, y1))
cell = gpd.GeoDataFrame(grid_cells, columns=['geometry'], crs=crs)
lng = cell.centroid.x
lat = cell.centroid.y

# Step 1: Generate a temporal API key to authentic the other API endpoints
headers = {
    'accept': 'application/json',
    # Already added when you pass json= but not when you pass data=
    # 'Content-Type': 'application/json',
}
json_data = {
    'email': email,
    'password': password,
}
# This the variable that holds the temporally API key
auth_response = requests.post('https://api.answr.space/api:auth/auth/login', headers=headers, json=json_data)
responses = []
if auth_response.status_code == 200:
    authkey = json.loads(auth_response.content)
    for i in range(len(cell)):
        # Step 2: Loop over the points and get the data from the answr.space API
        headers = {
            'accept': 'application/json',
            'Authorization': 'Bearer ' + authkey['authToken'] + '',
        }
        params = {
            'Input_point': '{"type":"point","data":{"lng":' + str(lng[i]) + ',"lat":' + str(lat[i]) + '}}',
        }
        response_1 = requests.get('https://api.answr.space/api:climate-variables/' + climatic_variable_1 + '',
                                  params=params,
                                  headers=headers)

        # Convert byte responses to json format
        climatic_variable_response = json.loads(response_1.content)
        if response_1.content != b'null':
            # Rename json to key to months for better plot visualization. You can find the response keys in the API reference documentation for each endpoint
            new_key = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October",
                       "November", "December"}
            old_key = {"CV76_M1", "CV76_M2", "CV76_M3", "CV76_M4", "CV76_M5", "CV76_M6", "CV76_M7", "CV76_M8",
                       "CV76_M9", "CV76_M10", "CV76_M11", "CV76_M12"}
            responses.append(dict(zip(new_key, list(climatic_variable_response.values()))))

        else:
            responses.append(dict(zip(new_key, [0]*12)))
    # Convert responses to data frame
    df_responses = pd.DataFrame(responses)
    plt.scatter(lng, lat, c = df_responses['March'], cmap= 'viridis')


else:
    print('Return status code: ' + str(auth_response.status_code))
    print(auth_response.content)

```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.answr.space/coding-examples/climatic-variables-spatial-plotting.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
