how to map netcdf data ob base map - geospatial

file contains values of echos w.r.t to lat/long, I have to plot complete range of echos over base map.
from netCDF4 import Dataset
import numpy as np
import pandas as pd
from google.colab import files
upload = files.upload()
my_example_nc_file = 'a.nc'
fh = Dataset(my_example_nc_file, mode='r')
lons = fh.variables['longitude'][:]
lats = fh.variables['latitude'][:]
ech= fh.variables['echos'][:]
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
%matplotlib inline
m = Basemap(width=5000000,height=3500000,
resolution='l',projection='stere',\
lat_ts=40,lat_0=lat_0,lon_0=lon_0)
xi, yi = m(lons, lats)
#simple plot
#m.plot(xi, yi, 'co')
m.scatter(rge,yi, marker = 'o', color='r', zorder=5)
Current code execute below results.
enter image description here
I want to plot total echos with variation represented by colors as presented in below screen short
enter image description here

Related

Annotating clustering from DBSCAN to original Pandas DataFrame

I have working code that is utilizing dbscan to find tight groups of sparse spatial data imported with pd.read_csv.
I am maintaining the original spatial data locations and would like to annotate the labels returned by dbscan for each data point to the original dataframe and then write a csv with the same information.
So the code below is doing exactly what I would expect it to at this point, I would just like to extend it to import the label for each row in the original dataframe.
import argparse
import string
import os, subprocess
import pathlib
import glob
import gzip
import re
import time
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from sklearn.cluster import DBSCAN
X = pd.read_csv(tmp_csv_name)
X = X.drop('Name', axis = 1)
X = X.drop('Type', axis = 1)
X = X.drop('SomeValue', axis = 1)
# only columns 'x' and 'y' now remain
db=DBSCAN(eps=EPS, min_samples=minSamples, metric='euclidean', algorithm='auto', leaf_size=30).fit(X)
labels = def_inst_dbsc.labels_
unique_labels = set(labels)
# maxX , maxY are manual inputs temporarily
while sizeX > 16 or sizeY > 16 :
sizeX=sizeX*0.8 ; sizeY=sizeY*0.8
fig, ax = plt.subplots(figsize=(sizeX,sizeY))
plt.xlim(0,maxX)
plt.ylim(0,maxY)
plt.scatter(X['x'], X['y'], c=colors, marker="o", picker=True)
# hackX , hackY are manual inputs temporarily
# which represent the boundaries defined in the original dataset
poly = patches.Polygon(xy=list(zip(hackX,hackY)), fill=False)
ax.add_patch(poly)
plt.show()

Scatter points assigned colour from CSV file

I am importing CSV data in the format x,y,z,p to plot a trisurface which has the scatter plots displayed on top.
The trisurface script works (ax.plot_trisurf), however, I would like to colour the scatter points (ax.scatter) according to either the 1 or -1 assigned in the fourth column of the CSV file.
enter image description here
The x,y,z data is complicated and can't be coloured, hence trying to assign it as simply as possible in the fourth column.
I have attached a basic image, essentially I just want to be able to have a selection of the red dots a different colour without affecting the trisurface they are on.
Any comments or suggestions are be very welcome!
My most recent error is:
ax.scatter(X, Y, np.log10(Z), c= (not p <= (0)({True: 'g', False: 'r'})), marker='o')
TypeError: 'int' object is not callable
enter code here
from typing import Any
import matplotlib
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import sys
import csv
import bbox
import matplotlib.ticker as mticker
# Import CSV data
from numpy import ndarray
csvFileName = sys.argv[0]
csvData = []
with open('ParvaluesMESS.csv', 'r') as csvfile:
csvReader = csv.reader(csvfile, delimiter=',')
for csvRow in csvReader:
csvData.append(csvRow)
csvData = np.array(csvData)
csvData = csvData.astype(float)
X, Y, Z, p = csvData[:,0], csvData[:,1], csvData[:,2], csvData[:,3]
# Plot management: note Z is logged
# Change vmin and vmax values for colorbar range if needed
# Alpha value is transparency
# 111 means 1x1 grid, first subplot
fig = plt.figure(figsize=(5,5))
ax = fig.add_subplot(111, projection='3d')
cb = ax.plot_trisurf(X, Y, np.log10(Z), cmap='coolwarm', alpha=0.75)
#cb = ax.plot_trisurf(X, Y, np.log10(Z), cmap='coolwarm', alpha=0.75, vmin=0, vmax=1)
ax.scatter(X, Y, np.log10(Z), col==(p > 0({True: 'g', False: 'r'})), marker='o')
#ax.zaxis._set_scale('log')
def log_tick_formatter(val, pos=None):
"""Reformat log ticks for display"""
return f"$10^{{{int(val)}}}$"
# Set Z axis to log
ax.zaxis.set_major_formatter(mticker.FuncFormatter(log_tick_formatter))
# ax.zaxis.set_major_locator(mticker.MaxNLocator(integer=True))
def ticklabels(ticks):
ticks_labels = []
for i in ticks:
ticks_labels.append(f'2^{np.log2(i)}')
return ticks_labels
fig.colorbar(cb, shrink=0.5)
ax.set_title("First-year sea ice PAR")
ax.set_xlabel("Ice Thickness m")
ax.set_ylabel("Snow thickness m")
ax.set_zlabel("µmol $^{m-2}$ $^{s-1}$")
ax.view_init(azim=70, elev=30)
ax.set_xlim3d(20, 350)
image_format = 'png' # e.g .png, .svg, etc.
image_name = 'test.eps'
plt.show()
fig.savefig(image_name, format=image_format, dpi=1200)
it was resolved by rearranging into arrays:
from typing import Any
import matplotlib
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import sys
import matplotlib.ticker as mticker
from numpy import ndarray
data=pd.read_csv('ParvaluesMESS.csv',header=None,sep=',',names=.
['Ice','Snow','umol','P'])
x=data[['Ice']].to_numpy()
y=data[['Snow']].to_numpy()
z=data[['umol']].to_numpy()
p=data[['P']].to_numpy()
x=(x.astype(float)).flatten()
y=(y.astype(float)).flatten()
z=(z.astype(float)).flatten()
p=(p.astype(float)).flatten()
fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(111, projection='3d')
cb = ax.plot_trisurf(x, y, np.log10(z), cmap='coolwarm', alpha=0.75)
ax.scatter(x, y, np.log10(z),c=p,cmap='RdYlGn')
#your formats
def log_tick_formatter(val, pos=None):
"""Reformat log ticks for display"""
return f"$10^{{{int(val)}}}$"
# Set Z axis to log
ax.zaxis.set_major_formatter(mticker.FuncFormatter(log_tick_formatter))
# ax.zaxis.set_major_locator(mticker.MaxNLocator(integer=True))
def ticklabels(ticks):
ticks_labels = []
for i in ticks:
ticks_labels.append(f'2^{np.log2(i)}')
return ticks_labels
fig.colorbar(cb, shrink=0.5)
ax.set_title("First-year sea ice PAR")
ax.set_xlabel("Ice Thickness m")
ax.set_ylabel("Snow thickness m")
ax.set_zlabel("µmol $^{m-2}$ $^{s-1}$")
ax.view_init(azim=70, elev=30)
ax.set_xlim3d(20, 350)
image_name = 'BenImag'
image_format = 'png' # e.g .png, .svg, etc.
plt.show()
fig.savefig(image_name, format=image_format, dpi=1200)

How to add color and legend by points' label one by one in python?

I want to divide and color points,val_lab(611,3) by their labels,pred_LAB(611,)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = plt.axes(projection = '3d')
ax.set_xlabel('L')
ax.set_ylabel('A')
ax.set_zlabel('B')
for i in range(0, len(val_lab)):
ax.scatter3D(
val_lab[i,0],
val_lab[i,1],
val_lab[i,2],
s = 8,
marker='o',
c = pred_LAB
#cmap = 'rainbow'
)
#ax.legend(*points.legend_elements(), title = 'clusters')
plt.show()
The problem is it shows error,
c' argument has 611 elements, which is not acceptable for use with 'x'
with size 1, 'y' with size 1.
However, if the dataset only have ten points,it can show the figure correctly, I don't know how to solve this problem, besides, how to add legend of this figure?
In your solution you would want to replace c = pred_LAB with c = pred_LAB[i]. But you do not have to use a for loop to plot the data. You can just use the following:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# generate random input data
val_lab = np.random.randint(0,10,(611,3))
pred_LAB = np.random.uniform(0,1, (611,))
# plot data
fig = plt.figure()
ax = plt.axes(projection = '3d')
ax.set_xlabel('L')
ax.set_ylabel('A')
ax.set_zlabel('B')
# create one 3D scatter plot - no for loop
ax.scatter3D(
val_lab[:,0],
val_lab[:,1],
val_lab[:,2],
s = 8,
marker='o',
c = pred_LAB,
cmap = 'rainbow',
label='my points'
)
# add legend
plt.legend()
plt.show()

How can I make a transparent background?

I have a .csv file which contains some data where x, y, x1, y1 are the coordinate points, and p is the value. My below code is working very well for plotting, but when I am plotting the data, I am getting a background color like the purple color. I don't want any color in the background. I want the background will be Transparent. My ultimate goal is overlying this result over an image. I am new in Python. Any help will be highly appreciated.
Download link of the .csv file here or link-2 or link-3
I am getting below result
My Code
import matplotlib.pyplot as plt
from scipy import ndimage
import numpy as np
import pandas as pd
from skimage import transform
from PIL import Image
import cv2
x_dim=1200
y_dim=1200
# Read CSV
df = pd.read_csv("flower_feature.csv")
# Create numpy array of zeros os same size
array = np.zeros((x_dim, y_dim), dtype=np.uint8)
for index, row in df.iterrows():
x = np.int(row["x"])
y = np.int(row["y"])
x1 = np.int(row["x1"])
y1 = np.int(row["y1"])
p = row["p"]
array[x:x1,y:y1] = p
map = ndimage.filters.gaussian_filter(array, sigma=16)
plt.imshow(map)
plt.show()
As per Ghassen's suggestion I am getting below results. I am still not getting the transparent background.
When Alpha =0
When alpha =0.5
When alpha =1
try with this code :
import matplotlib.pyplot as plt
from scipy import ndimage
import numpy as np
import pandas as pd
x_dim=1200
y_dim=1200
# Read CSV
df = pd.read_csv("/home/rosafi/Downloads/flower_feature.csv")
# Create numpy array of zeros os same size
array = np.ones((x_dim, y_dim), dtype=np.uint8)
for index, row in df.iterrows():
x = np.int(row["x"])
y = np.int(row["y"])
x1 = np.int(row["x1"])
y1 = np.int(row["y1"])
p = row["p"]
array[x:x1,y:y1] = p
map = ndimage.filters.gaussian_filter(array, sigma=16)
map = np.ma.masked_where(map == 0, map)
plt.imshow(map)
plt.show()
output:
I solved this issue by masking out the values where values ==0. The code will be
from mpl_toolkits.axes_grid1 import make_axes_locatable
masked_data = np.ma.masked_where(map == 0, map)

Store the Spectrogram as Image in Python

I want to store the STFT spectrogram of the audio as image. The code below shows a spectrogram to me as output, but when saved as image I get a different image.
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
audio_name = '---.au'
hop_length = 512
window_size = 1024
import librosa
y, sr = librosa.load(audio_name)
window = np.hanning(window_size)
out = librosa.core.spectrum.stft(y, n_fft = window_size, hop_length = hop_length,
window=window)
out = 2 * np.abs(out) / np.sum(window)
import librosa.display
librosa.display.specshow(librosa.amplitude_to_db(out,ref=np.max),
y_axis='log', x_axis='time')
from PIL import Image
img = Image.fromarray(out)
if img.mode != 'RGBA':
img = img.convert('RGBA')
img.save('output.png')
But when I save it the output file is a black image.
I want to save the exact image of the spectogrm.
If you want exactly what librosa.display.spectrogram() will show, then use matplotlib to save the plot to a file:
import matplotlib.pyplot as plt
import librosa.display
import numpy as np
import pandas as pd
import librosa
filename = librosa.util.example_audio_file()
y, sr = librosa.load(filename)
y = y[:100000] # shorten audio a bit for speed
window_size = 1024
window = np.hanning(window_size)
stft = librosa.core.spectrum.stft(y, n_fft=window_size, hop_length=512, window=window)
out = 2 * np.abs(stft) / np.sum(window)
# For plotting headlessly
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
fig = plt.Figure()
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
p = librosa.display.specshow(librosa.amplitude_to_db(out, ref=np.max), ax=ax, y_axis='log', x_axis='time')
fig.savefig('spec.png')
spec.png:
If the desired is to get just the data in the spectrogram, stored as an image, then see this answer.

Resources