1 | ############################################################## |
---|
2 | ### Python script to visualize a variable in a NetCDF file ### |
---|
3 | ############################################################## |
---|
4 | |
---|
5 | ### This script can display any variable of a NetCDF file. |
---|
6 | ### The file name, the variable to display and eventually the |
---|
7 | ### dimension are asked to the user in the terminal. |
---|
8 | |
---|
9 | import os |
---|
10 | import readline |
---|
11 | import glob |
---|
12 | from netCDF4 import Dataset |
---|
13 | import matplotlib.pyplot as plt |
---|
14 | import numpy as np |
---|
15 | |
---|
16 | ############################################################## |
---|
17 | ### Setup readline for file name autocompletion |
---|
18 | def complete(text,state): |
---|
19 | line = readline.get_line_buffer().split() |
---|
20 | # Use glob to find all matching files/directories for the current text |
---|
21 | if '*' not in text: |
---|
22 | text += '*' |
---|
23 | matches = glob.glob(os.path.expanduser(text)) |
---|
24 | # Add '/' if the match is a directory |
---|
25 | matches = [match + '/' if os.path.isdir(match) else match for match in matches] |
---|
26 | |
---|
27 | try: |
---|
28 | return matches[state] |
---|
29 | except IndexError: |
---|
30 | return None |
---|
31 | |
---|
32 | ### Function to handle autocomplete for variable names |
---|
33 | def complete_variable_names(variable_names): |
---|
34 | def completer(text, state): |
---|
35 | options = [name for name in variable_names if name.startswith(text)] |
---|
36 | if state < len(options): |
---|
37 | return options[state] |
---|
38 | else: |
---|
39 | return None |
---|
40 | return completer |
---|
41 | |
---|
42 | ### Function to visualize a variable from a NetCDF file |
---|
43 | def visualize_variable(): |
---|
44 | # Ask for the NetCDF file name |
---|
45 | readline.set_completer(complete) |
---|
46 | readline.parse_and_bind('tab: complete') |
---|
47 | file = input("Enter the name of the NetCDF file: ") |
---|
48 | |
---|
49 | # Open the NetCDF file |
---|
50 | try: |
---|
51 | dataset = Dataset(file,mode='r') |
---|
52 | except FileNotFoundError: |
---|
53 | print(f"File '{file}' not found.") |
---|
54 | return |
---|
55 | |
---|
56 | # Display available variables |
---|
57 | variable_names = list(dataset.variables.keys()) |
---|
58 | print("Available variables:\n",variable_names) |
---|
59 | |
---|
60 | # Ask for the variable to display |
---|
61 | readline.set_completer(complete_variable_names(variable_names)) |
---|
62 | variable_name = input("\nEnter the name of the variable you want to visualize: ") |
---|
63 | |
---|
64 | # Check if the variable exists |
---|
65 | if variable_name not in dataset.variables: |
---|
66 | print(f"Variable '{variable_name}' not found in the dataset.") |
---|
67 | dataset.close() |
---|
68 | return |
---|
69 | |
---|
70 | # Extract the selected variable |
---|
71 | variable = dataset.variables[variable_name][:] |
---|
72 | |
---|
73 | # Extract latitude, longitude and altitude |
---|
74 | latitude = dataset.variables['latitude'][:] |
---|
75 | longitude = dataset.variables['longitude'][:] |
---|
76 | |
---|
77 | # Check if the variable has altitude and time dimensions |
---|
78 | dimensions = dataset.variables[variable_name].dimensions |
---|
79 | print(f"\nDimensions of '{variable_name}': {dimensions}") |
---|
80 | |
---|
81 | # If the variable has a time dimension, ask for the time index |
---|
82 | if 'Time' in dimensions: |
---|
83 | time_index = int(input(f"Enter the time index (0 to {variable.shape[0] - 1}): ")) |
---|
84 | else: |
---|
85 | time_index = None |
---|
86 | |
---|
87 | # If the variable has an altitude dimension, ask for the altitude index |
---|
88 | if 'altitude' in dimensions: |
---|
89 | altitude = dataset.variables['altitude'][:] |
---|
90 | altitude_index = int(input(f"Enter the altitude index (0 to {altitude.shape[0] - 1}): ")) |
---|
91 | else: |
---|
92 | altitude_index = None |
---|
93 | |
---|
94 | # Prepare the 2D slice for plotting |
---|
95 | if time_index is not None and altitude_index is not None: |
---|
96 | data_slice = variable[time_index,altitude_index,:,:] |
---|
97 | elif time_index is not None: |
---|
98 | data_slice = variable[time_index,:,:] |
---|
99 | elif altitude_index is not None: |
---|
100 | data_slice = variable[altitude_index,:,:] |
---|
101 | else: |
---|
102 | data_slice = variable[:,:] |
---|
103 | |
---|
104 | # Plot the selected variable |
---|
105 | plt.figure(figsize=(10,6)) |
---|
106 | plt.contourf(longitude,latitude,data_slice,cmap='viridis') |
---|
107 | plt.colorbar(label=f"{variable_name.capitalize()} (units)") # Adjust units based on your data |
---|
108 | plt.xlabel('Longitude (degrees)') |
---|
109 | plt.ylabel('Latitude (degrees)') |
---|
110 | plt.title(f"{variable_name.capitalize()} visualization") |
---|
111 | |
---|
112 | # Show the plot |
---|
113 | plt.show() |
---|
114 | |
---|
115 | # Close the NetCDF file |
---|
116 | dataset.close() |
---|
117 | |
---|
118 | ### Call the main function |
---|
119 | visualize_variable() |
---|