-2

i have converted a csv file into nc file and tried to map it with python cartophy but it is showing an error that the temperature data is 1D. how can i solve this

i have tried some codes to create a geographic map and expected to show the temperature variations of this region but it only showing the map without the temperature data.

import pandas as pd
import os
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from scipy.interpolate import griddata

# Load the reference CSV file into a DataFrame
 reference_file_path = "C:/Users/ACER/Desktop/python 
prac/meghna_pcp_station.csv"
reference_df = pd.read_csv(reference_file_path)

# Create an empty DataFrame to store the merged data
merged_df = pd.DataFrame()

# Get the list of CSV files in the directory
directory_path = "C:/Users/ACER/Desktop/python prac"
csv_files = [file for file in os.listdir(directory_path) if 
file.endswith(".csv")]

# Iterate over the CSV files, read each file into a DataFrame, merge 
it with the reference DataFrame based on the "name" column,
# and append it to the merged_df DataFrame
for csv_file in csv_files:
    file_path = os.path.join(directory_path, csv_file)
    NAME = os.path.splitext(csv_file)[0]  # Extract the name from the 
    file
    data_df = pd.read_csv(file_path)
    data_df["NAME"] = NAME
    merged_data = pd.merge(data_df, reference_df, on="NAME", 
    how="inner")
    merged_df = merged_df.append(merged_data, ignore_index=True)



   # Create a figure and axis for the plot
fig, ax = plt.subplots(figsize=(10, 10), subplot_kw={"projection": 
ccrs.PlateCarree()})

# Add map features
ax.coastlines()
ax.add_feature(cfeature.BORDERS)
ax.add_feature(cfeature.LAND, facecolor="lightgray")
ax.add_feature(cfeature.OCEAN, facecolor="white")

# Plot the temperature distribution on the map
#sc = ax.scatter(merged_df["LONGITUDE"], merged_df["LATITUDE"], 
c=merged_df["Temperature"], cmap="coolwarm", s=10, 
edgecolors="black")


# Define the latitude and longitude values
lat = merged_df["LONGITUDE"].values
lon = merged_df["LATITUDE"].values

# Define the temperature values
temperature = merged_df["Temperature"].values

# Create a regular grid for interpolation
lon_grid, lat_grid = np.meshgrid(np.linspace(min(lon), max(lon), 
100), np.linspace(min(lat), max(lat), 100))

# Interpolate the temperature values onto the grid
 temperature_grid = griddata((lon, lat), temperature, (lon_grid, 
lat_grid), method="linear")

vmin = min(temperature)
vmax = max(temperature)

# Plot the temperature data as a heatmap
heatmap = ax.imshow(temperature_grid, extent=[min(lon), max(lon), 
min(lat), max(lat)], cmap="warm", origin="lower", aspect="auto")

# Plot the temperature distribution on the map
#cf = ax.contourf(lon, lat, temperature, cmap="coolwarm")

# Add a colorbar
#cbar = plt.colorbar(sc, label="Temperature")
cbar = plt.colorbar(heatmap, label="Temperature")

# Set plot title
plt.title("Temperature Distribution")

# Show the plot
plt.show()

1 Answers1

0

It's not your code, although that might have some issues as well, but more likely it's your data that it's causing the problem. Since you don't provide a reproducible example, it's impossible to tell of course.

The code below is a simplified toy example, starting with randomly scattered points that get interpolated to a regular grid.

You might have the origin wrong, but that should become obvious if you plot the raw data points over it.

Also note that defining the extent like this is incorrect because Matplotlib expect the outer extent, where you (and I've copied that) provide the center of the corner pixels. So it's off by half the resolution of the grid, perhaps acceptable for your application, but not correct. I would personally be more explicit with the resolution of the target grid, it's now 100 elements between the min/max of your data, would that make the final resolution data dependent (eg change with new data)? That's very subjective of course, but relates to specifying the correct extent, which is more difficult to do like this.

import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from scipy.interpolate import griddata

rng = np.random.default_rng(seed=2)
lat = rng.integers(-80, 80, 50)
lon = rng.integers(-160, 160, 50)
temperature = rng.random(50)

lonn = lon.min()
lonx = lon.max()
latn = lat.min()
latx = lat.max()

lat_grid, lon_grid = np.mgrid[latx:latn:-1, lonn:lonx:1]

temperature_grid = griddata(
    (lon, lat), temperature, (lon_grid, lat_grid), method="linear",
)

projection = ccrs.PlateCarree()
fig, ax = plt.subplots(
    figsize=(10, 5), facecolor="w",
    subplot_kw={"projection": projection},
)

ax.set_title("Temperature Distribution")
ax.coastlines(color="k")

ax.plot(lon, lat, "wo", ms=6, mfc="k", mew=1.5, transform=projection)

im = ax.imshow(
    temperature_grid, extent=[lonn, lonx, latn, latx], 
    cmap="inferno", origin="upper", transform=projection,
)
cb = fig.colorbar(im, ax=ax, label="Temperature", shrink=.5)

enter image description here

Rutger Kassies
  • 61,630
  • 17
  • 112
  • 97