IndexError: too many indices for array: array is 1-dimensional, but 2 were indexed while Plotting a grid

Viewed 1086

first I would like to explain what I have done so far! The aim of my work is to interpolate data from different measuring stations, then take the mean value of the values of the individual interpolated grids (from different years) and plot them. The grid I used for this looks like this:

def generate_grid(data, basemap, delta=30):
    grid = {
        'lon': np.arange(-180, 180, delta),
        'lat': np.arange(-89.9,89.9, delta) 
    }
    grid["x"], grid["y"] = np.meshgrid(grid["lon"], grid["lat"])
    grid["x"], grid["y"] = basemap(grid["x"], grid["y"])
    return grid

I then exported the grid data as a CSV file.

def inter_todf(interpolation, grid):
    grid['x'], grid['y'] = basemap(grid['x'],grid['y'],inverse=True) # Wandelt Grid in Long und Lat wieder um 
    dfl = pd.DataFrame({
        'Latitude': grid['y'].reshape(-1),
        'Longitude': grid['x'].reshape(-1),
        'Value': interpolation.reshape(-1)
        });
    return(dfl)
dfl= inter_todf(interpolation, grid)
dfl.to_csv(plot_folder+'Dezember/'+file.replace(".csv", "grid.csv"))

I do not show the averaging step, as it is irrelevant. So my averaged data looks like this:

       Unnamed: 0  Latitude  Longitude     Value
0               0     -89.9     -180.0 -7.414481
1               1     -89.9     -179.0 -7.413804
2               2     -89.9     -178.0 -7.413334
3               3     -89.9     -177.0 -7.413073
4               4     -89.9     -176.0 -7.413023
...           ...       ...        ...       ...
64795       64795      89.1      175.0 -7.790705
64796       64796      89.1      176.0 -7.783264
64797       64797      89.1      177.0 -7.776208
64798       64798      89.1      178.0 -7.769540
64799       64799      89.1      179.0 -7.763257

[64800 rows x 4 columns]

The CSV file has Lat, Long and Value data: https://filebin.net/n9mnzakasaf6tb0g

Now I want to plot this data again in Basemap and have written this so far.

from traceback import print_tb
import numpy as np
from pykrige.ok import OrdinaryKriging
from pykrige.kriging_tools import write_asc_grid
import pykrige.kriging_tools as kt
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from matplotlib.patches import Path, PathPatch
import pandas as pd
def load_data():
    df = pd.read_csv(r"C:File")
    return(df)

def get_data(df):
    return {
        "lons": df['Longitude'].values,
        "lats": df['Latitude'].values,
        "values": df['Value'].values
    }

def generate_grid(data, basemap, delta=1):
    grid["x"], grid["y"] = (data["lons"], data["lats"])
    grid["x"], grid["y"] = basemap(grid["x"], grid["y"])
    return grid

def prepare_map_plot():
    figure, axes = plt.subplots(figsize=(10,10))
    basemap = Basemap(projection='robin', lon_0=0, lat_0=0, resolution='l',area_thresh=1000000,ax=axes) 
    basemap.drawcoastlines() 
    return figure, axes, basemap

def plot_mesh_data(data, grid, basemap):
    shape = (len(np.unique(grid['x'])), len(np.unique(grid['y'])))
    colormesh = basemap.contourf(grid["x"].reshape(shape), grid["y"].reshape(shape),  data['values'].reshape(shape),32, cmap='RdBu_r', )
    color_bar = basemap.colorbar(colormesh,location='bottom',pad="10%") 


df = load_data()
base_data = get_data(df)
# print(df['Latitude'].shape)
figure, axes, basemap = prepare_map_plot()
grid = generate_grid(base_data, basemap, 90)
plot_mesh_data(base_data, grid,basemap)
plt.show()

However, I keep getting errors such as;

IndexError: too many indices for array: array is 1-dimensional, but 2 were indexed
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in plot_mesh_data
  File "C:\Users\O\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\mpl_toolkits\basemap\__init__.py", line 536, in with_transform
    return plotfunc(self,x,y,data,*args,**kwargs)
  File "C:\Users\O\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\mpl_toolkits\basemap\__init__.py", line 3653, in contourf
    xx = x[x.shape[0]//2,:]
IndexError: too many indices for array: array is 1-dimensional, but 2 were indexed

What can I do better and how can I plot the gridded data, so that The result look like this: enter image description here

2 Answers

the first three arguments to contourf are expected to be 2d arrays, such as the outputs of np.meshgrid, whereas you are using the flattened arrays. The quick and hacky way to resolve this is to reshape the input to contourf right where the exception is caused in your code.

Apart from that, you are making the mistake to have a regular grid in lon-lat coordinates, which will not translate to a regular grid on the sphere. Instead, you are having a larger density of data-points at the poles than close to the equator. The hacky way to solve this would be to make the number of longitude values scale by a factor of cos(latitude). The correct way to solve this would be to use some algorithm to subdivide the sphere into equally areas (e.g. healpix, but other algorithms also exist; I've used a simple Fibonacci lattice and it served me well enough once in a while).

So Thomas is close on this one. Hes right, colormesh expects 2d arrays. This works well if you are generating an array of x and y data, and say your z values could be solved via some formula from them. And I think the unique shape would also have worked, but you have already converted your x and y from map coordinates to plot coordinates.

Im not sure if this will give you your correct colors, but you could force them into 2d arrays while keeping your x,y,z's lined up by reshaping them all via

shape = (int(len(grid['x')/2),2)

That should work since your len is 64800, an even number. I was able to get that to plot without errors, but I only used your snippet of data above, not the whole file.

Related