Get contour coordinates using alphashape - python

I have plotted the contour of some data from file, but I need to generate a file with the coordinates of this contour. My code is the following:
import os
import sys
import pandas as pd
import numpy as np
from descartes import PolygonPatch
import matplotlib.pyplot as plt
sys.path.insert(0, os.path.dirname(os.getcwd()))
import alphashape
data1 = pd.read_csv('SDSS_19.txt', sep='\s+', header=None)
data1 = pd.DataFrame(data1)
x = data1[0]
y = data1[1]
points = np.vstack((x, y)).T
fig, ax = plt.subplots(figsize=(20,20))
ax.scatter(x, y, alpha=0.5, color='red')
alpha_shape = alphashape.alphashape(points, 0.6)
ax.add_patch(PolygonPatch(alpha_shape, alpha=0.25))
plt.savefig('contour.png')
plt.show()
The output is the following:
What I need is to calculate the coordinates of some points (the more the best) of the black line (the contour).
any help? Thanks.

Related

Fit of intensity distribution does not work

So im sitting here and don't know how to fit the right function for my Intensity distribution of a doubleslit experiment. I tried so much but I don't know how it works. The x,y data are more than 1000 values.
Here is my Plot:
And here's how it should look like:
And that is my code to that:
import matplotlib.patches as mp
import matplotlib.pyplot as plt
import numpy as np
from scipy import optimize
from scipy.optimize import curve_fit
import pandas as pd
import math
data = pd.read_csv('TEM00-Doppelspalt-Short.txt',sep='\s+',header=None)
data = pd.DataFrame(data)
x = data[1]
y = data[2]
def expf(i0,g,k,y0,d):
return i0*((np.sin(g*(k-y0)))/(g*(k-y0)))**2*np.cos(d*(k-y0))**2
popt, pcov =curve_fit(expf, x, y, p0 = (13, 20, 2, 4))
g,k,y0,d = popt
plt.figure(figsize = (8,6), dpi = 600)
plt.xlabel(r'Wavelength [$\mu$m]',fontsize=12)
plt.ylabel('Value [Cnts]', fontsize=12)
plt.plot(x, y,'ko')
plt.plot(x, expf(x,g,k,y0,d))
a_patch=mp.Patch(color='k', label="$TEM_{00}$ Doubleslit ShortMode")
plt.legend(handles=[a_patch],loc="upper left")
plt.show()
Here is my datafile:
Data File of Intensity

Fixing mollweide matplotlib projection contours

I am having problems in making mollweide plots in the borders. The lines do not continue on the other side of the plot.
Is there any way to fix this (the green curve should continue in the other side of the sphere )? I am using matplotlib projections. The code is plotting circles of known radius and known center but matplotlib is just cutting the lines. How I could solve this?
import math
import numpy as np
import getdist.plots as plots
import matplotlib.pyplot as plt
import matplotlib.ticker
import matplotlib
import scipy
import pandas as pd
from scipy.stats import norm
from matplotlib import rc
from getdist import loadMCSamples
from getdist import loadMCSamples
from getdist import covmat
from getdist import MCSamples
from tabulate import tabulate
from scipy.optimize import curve_fit
from matplotlib.projections.geo import GeoAxes
from mpl_toolkits.mplot3d import Axes3D
class ThetaFormatterShiftPi(GeoAxes.ThetaFormatter):
"""Shifts labelling by pi
Shifts labelling from -180,180 to 0-360"""
def __call__(self, x, pos=None):
if x != 0:
x *= -1
if x < 0:
x += 2*np.pi
return GeoAxes.ThetaFormatter.__call__(self, x, pos)
mean1024 = [1,186,48]
sigma1024 = 30
x = np.linspace(-6.0, 6.0, 100)
y = np.linspace(-6.0, 6.0, 100)
X, Y = np.meshgrid(x,y)
l = (360.-mean1024[1])/(180/np.pi)
b = (mean1024[2])/(180/np.pi)
F = (X-l)**2 + (Y-b)**2 - (sigma1024/(180/np.pi))**2
F2 = (X-l)**2 + (Y-b)**2 - (2*sigma1024/(180/np.pi))**2
fig, axs = plt.subplots(figsize=(15,10))
axs = plt.subplot(projection="mollweide")
axs.set_longitude_grid(45)
axs.xaxis.set_major_formatter(ThetaFormatterShiftPi(45))
axs.set_latitude_grid(45)
axs.set_longitude_grid_ends(90)
plt.grid(True)
axs.contour(X,Y,F,[0], linewidths=1.5, colors = ['g'])
axs.contour(X,Y,F2,[0], linewidths=1.5, colors = ['g'])
plt.plot(l, b, '+', color = 'green')
box = axs.get_position()
axs.set_position([box.x0, box.y0, box.width * 0.8, box.height*0.8])
axs.legend(loc='lower right', bbox_to_anchor=(1.1, -0.2))
fig.savefig('circles.png')
plt.close()

3D plot using geographic coordinates

I have a dataset looking like this:
1 38.7114 -7.92482 16.4375 0.2
...
I'd like to make a 3D scatter plot. I've done it using cartesian coordinates. How I can do it using geographic coordinates? Any hint?
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import sys
from mpl_toolkits.basemap import Basemap
ID=[]
Latitude=[]
Longitude=[]
Depth=[]
cluster1='data1'
with open(cluster1) as f:
lines = f.readlines()
for line in lines:
items = line.strip().split()
lat = float(items[1])
lon = float(items[2])
dep = float(items[3])
mag = float(items[4])
Latitude.append(lat)
Longitude.append(lon)
Depth.append(dep)
ID.append(mag)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
p = ax.scatter(Longitude, Latitude, Depth, c=ID, marker='o')
ax.set_xlabel('Longitude')
ax.set_ylabel('Latitude')
ax.set_zlabel('Depth (km)')
ax.invert_zaxis()
cb = fig.colorbar(p,label='Magnitude')
plt.savefig('plot1.png')

Contours Not Plotting

I'm trying to plot contours of ash deposit depth using Basemap and matplotlib. For some reason, my contours aren't showing up and I can't see what I'm missing.
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from netCDF4 import Dataset
from mpl_toolkits.basemap import Basemap
url = "BigAsh_DepoThick.nc"
data = Dataset(url, mode="r")
times = data.variables["time"]
lats = data.variables["Lat"][:]
lons = data.variables["Lon"][:]
depths = data.variables["DepoThick"][:,:,:]
fig=plt.figure(figsize=(16,8))
# Create the map
m = Basemap(llcrnrlon=-150,llcrnrlat=10,urcrnrlon=-60,urcrnrlat=70,
projection='merc', resolution ='l')
m.drawcoastlines(linewidth=1)
m.drawstates(linewidth=1)
m.drawcountries(linewidth=1)
m.fillcontinents(color='gray')
plons, plats = np.meshgrid(lons, lats)
x, y = m(plons, plats)
cp = m.contourf(x, y, depths[-1,:,:], 100)
cbar = plt.colorbar(cp)
cbar.set_label("Ash Depth [mm]")
plt.title("Mt. St. Helens Ash Depth")
plt.show()

Matplotlib discretize colorbar between given values

I have the plot bellow and I would like to discretize the colormap between 0 and 20. Could anyone help with that?
Here is the code:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import BoundaryNorm
from matplotlib.ticker import MaxNLocator
epi='epi'
with open(epi, 'r') as f2:
lines = f2.readlines()
data = [line.split() for line in lines]
a = np.array(data)
print a.shape
lat = a[:,0]
lat1=list(lat)
lat2=np.asarray(lat1).astype(float)
lon = a[:,1]
lon1=list(lon)
lon2=np.asarray(lon).astype(float)
x_space = 60
y_space = x_space*1.7
gridx = np.linspace(-8.8, -7.0, x_space)
gridy = np.linspace(38, 39.5, y_space )
grid, _, _ = np.histogram2d(lat2, lon2, bins=[gridy, gridx])
cmap = plt.get_cmap('hot_r')
plt.figure()
plt.axis((-8.8,-7.0,38.2,39))
plt.pcolormesh(gridx, gridy, grid,cmap=cmap)
plt.colorbar()
plt.show()
If you want a coarsely discretized colormap, you can change your get_cmap call and include the number of different (discrete) colors you want:
import matplotlib.pylab as pl
import numpy as np
data = np.random.random([10,10]) * 40
hot2 = pl.cm.get_cmap('hot', 20)
pl.figure()
pl.subplot(121)
pl.pcolormesh(data, cmap=pl.cm.hot, vmin=0, vmax=20)
pl.colorbar()
pl.subplot(122)
pl.pcolormesh(data, cmap=hot2, vmin=0, vmax=20)
pl.colorbar()

Categories