pcolormesh shading='gouraud' not working - python

I am trying to smooth my color map using pcolormesh shading='gouraud' argument, but it failed, returned the follow error, which I do not understand.
"/usr/local/anaconda/lib/python2.7/site- packages/matplotlib/collections.py", line 1822, in draw
gc, triangles, colors, transform.frozen())
File "/usr/local/anaconda/lib/python2.7/site-packages/matplotlib/backends/backend_ps.py", line 876, in draw_gouraud_triangles
('colors', 'u1', (3,))])
TypeError: data type not understood File
I have my code as below:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rcParams
from matplotlib.mlab import griddata
from matplotlib.ticker import AutoMinorLocator
from mpl_toolkits.axes_grid1 import make_axes_locatable
from mpl_toolkits.basemap import Basemap
x = np.loadtxt('data.txt',usecols=[0])
y = np.loadtxt('data.txt',usecols=[1])
s = np.loadtxt('data.txt',usecols=[2])
N = 36j
M = 18j
extent = (min(x), max(x), min(y), max(y))
xx,yy = np.mgrid[extent[0]:extent[1]:N, extent[2]:extent[3]:M]
ss = griddata(x, y, s, xx, yy, interp='linear')
fig, ax = plt.subplots()
#m = Basemap(projection='hammer',lon_0=0,resolution=None)
m = Basemap(projection='kav7',lon_0=0,resolution=None)
m.drawmapboundary(fill_color='0.75')
im = m.pcolormesh(xx,yy,ss,shading='gouraud',cmap=plt.cm.jet,latlon=True)
m.drawparallels(np.arange(-90.,99.,30.))
m.drawmeridians(np.arange(-180.,180.,60.))
cb = m.colorbar(im,"bottom", size="5%", pad="2%", ticks=[-2,-1,0,1,2,3,4,5])
plt.show()
When the shading argument is flat shading = 'flat', then this works very well, but the color is not smooth. Any one can offer me some idea how to approach this problem?

Related

Spatial interpolation of discrete points onto x/y coordinate mesh grid in Python

I'm still very new to programming and trying to create a contour plot of alkalinity across Hawaii using Cartopy. I will need to interpolate the point values called MODIFIED_TA against an x-y mesh grid but have not been able to figure out how to do this. The code I'm using is:
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import cartopy.crs as ccrs
import cartopy.mpl.ticker as cticker
import statistics
from scipy.interpolate import UnivariateSpline
import numpy as np
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
import warnings
warnings.filterwarnings("ignore") # ignoring the warning prompts.
%matplotlib inline
fig = plt.figure(figsize=(15,15))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree(central_longitude=-170))
landgreen = cfeature.NaturalEarthFeature('physical', 'land', '110m',
edgecolor='face', facecolor='green')
oceanaqua = cfeature.NaturalEarthFeature('physical', 'ocean', '110m',
edgecolor='face', facecolor='aqua')
ax.set_extent([-151.5, -162, 18, 24], ccrs.PlateCarree())
ax.set_title('TOTAL ALKALINITY')
ax.add_feature(landgreen)
ax.add_feature(cfeature.OCEAN, color = 'k')
ax.gridlines(draw_labels=True)
lon_formatter = cticker.LongitudeFormatter()
lat_formatter = cticker.LatitudeFormatter()
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)
ax.grid(linewidth=2, color='black', alpha=0.5, linestyle='--')
lons = all_data.LONGITUDE[:]
lats = all_data.LATITUDE[:]
alk = all_data.MODIFIED_TA[:]
x1,y1 = np.meshgrid(lons,lats)
z1,z2 = np.meshgrid(all_data.MODIFIED_TA,all_data.MODIFIED_TA)
plt.tricontourf(lons,lats,alk, transform=ccrs.PlateCarree(), cmap=cm.gist_rainbow)
plt.colorbar(shrink=0.5)
plt.title('$A_{T}$ VALUES', color = 'k', fontname='Times New Roman',size = 23)
plt.plot()
The result is nothing like what I was hoping for and again, I'm not sure how to interpolate this value so that it comes out as a smooth gradient across the x/y coordinate grid. Any help would be greatly appreciated!
See output here
It's hard to tell for sure without being able to see your data. I tried to create a MRE and it worked. I would start by seeing if this works.
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.mpl.ticker as cticker
import numpy as np
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree(central_longitude=-170))
ax.set_extent([-151.5, -162, 18, 24], ccrs.PlateCarree())
ax.add_feature(cfeature.OCEAN)
ax.gridlines(draw_labels=True)
lon_formatter = cticker.LongitudeFormatter()
lat_formatter = cticker.LatitudeFormatter()
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)
ax.grid(linewidth=2, color='black', alpha=0.5, linestyle='--')
lons = np.random.random(80) * 7 - 160
lats = np.random.random(80) * 4 + 19
alk = np.cos(lons * 10 * np.pi / 180) * np.sin(lats * 20 / 180)
plt.plot(lons, lats, 'k.', transform = ccrs.PlateCarree())
plt.tricontourf(lons,lats,alk, transform=ccrs.PlateCarree(), alpha = 0.5)
plt.colorbar(shrink=0.5)
plt.title('$A_{T}$ VALUES', color = 'k', fontname='Times New Roman',size = 23)
If it does work, then what I'd look at would include:
What are the dimensions of all_data.LONGITUDE, all_data.LATITUDE, all_data.MOTIFIED_TA?
Are there duplicate values?
Does it work when you plot it outside of a projection?
If my example does not work, then it suggests there is something about your install, in which case update it if you can. If the problem still persists, perhaps there is a bug cartopy that needs reporting or a conflict with other packages.
Sorry, I cannot help further.

Draw a (2D/3D) graph given the adjancecy matrix and the corrdinates of the nodes with matplotlib

I am trying to plot a graph given the adjancecy matrix and the coordinates of the nodes with this code below, using matplotlib. Yet when I vizualize the graph, it's not the same as the adjancecy matrix, and mainly some edges are missing. Any insights?
NB: for now I am only plotting 2D Graph so my Z are 0, so if you have any other idea on how to do so (maybe with networkx) I'll appreciate your help too
from scipy.spatial import Delaunay
import numpy as np
#from numpy import sin, cos, sqrt
import matplotlib.tri as mtri
#from sklearn import preprocessing
import mpl_toolkits.mplot3d as plt3d
import matplotlib.pyplot as plt
plt.rcParams.update({'figure.max_open_warning': 0})
plt.switch_backend('agg')
def draw_surface( points_coord, adj):
'''points_coord.shape: (num_points, coord=3),
adj.shape:(num_points,num_points)'''
name= 'img'
fig = plt.figure(figsize=(12,10))
# Plot the surface.
ax = fig.add_subplot(1, 1, 1, projection='3d')
#ax.plot_trisurf(triang, z, cmap=cm.jet)#cmap=plt.cm.CMRmap)
x = points_coord[:,0]
y = points_coord[:,1]
if len(points_coord) == 3:
z = points_coord[:,2]
else:
z = np.zeros_like(points_coord[:,0])
max_val = np.max(adj)
list_edges = []
#plot lines from edges
for i in range(adj.shape[0]):
for j in range(i,adj.shape[1]):
if adj[i][j]:
line = plt3d.art3d.Line3D([x[i],x[j]], [y[i],y[j]], [z[i],z[j]], \
linewidth=0.4, c="black", alpha = round( adj[i,j], 4 ))
list_edges.append((i,j))
ax.add_line(line)
ax.scatter(x,y,z, marker='.', s=15, c="blue", alpha=0.6)
#ax.view_init(azim=25)
plt.axis('off')
plt.show()
plt.savefig(name+'.png', dpi=120)
plt.clf()

Putting matplotlib hexbin into an Aitoff projection

I have the nice hexbin plot below, but I'm wondering if there is any way to get hexbin into an Aitoff projection? The salient code is:
import numpy as np
import math
import matplotlib.pyplot as plt
from astropy.io import ascii
filename = 'WISE_W4SNRge3_and_W4MPRO_lt_6.0_RADecl_nohdr.dat'
datafile= path+filename
data = ascii.read(datafile)
points = np.array([data['ra'], data['dec']])
color_map = plt.cm.Spectral_r
points = np.array([data['ra'], data['dec']])
xbnds = np.array([ 0.0,360.0])
ybnds = np.array([-90.0,90.0])
extent = [xbnds[0],xbnds[1],ybnds[0],ybnds[1]]
fig = plt.figure(figsize=(6, 4))
ax = fig.add_subplot(111)
x, y = points
gsize = 45
image = plt.hexbin(x,y,cmap=color_map,
gridsize=gsize,extent=extent,mincnt=1,bins='log')
counts = image.get_array()
ncnts = np.count_nonzero(np.power(10,counts))
verts = image.get_offsets()
ax.set_xlim(xbnds)
ax.set_ylim(ybnds)
plt.xlabel('R.A.')
plt.ylabel(r'Decl.')
plt.grid(True)
cb = plt.colorbar(image, spacing='uniform', extend='max')
plt.show()
and I've tried:
plt.subplot(111, projection="aitoff")
before doing the plt.hexbin command, but which only gives a nice, but blank, Aitoff grid.
The problem is that the Aitoff projection uses radians, from -π to +π. Not degrees from 0 to 360. I use the Angle.wrap_at function to achieve this, as per this Astropy example (which essentially tells you how to create a proper Aitoff projection plot).
In addition, you can't change the axis limits (that'll lead to an error), and shouldn't use extent (as ImportanceOfBeingErnest's answer also states).
You can change your code as follows to get what you want:
import numpy as np
import matplotlib.pyplot as plt
from astropy.io import ascii
from astropy.coordinates import SkyCoord
from astropy import units
filename = 'WISE_W4SNRge3_and_W4MPRO_lt_6.0_RADecl_nohdr.dat'
data = ascii.read(filename)
coords = SkyCoord(ra=data['ra'], dec=data['dec'], unit='degree')
ra = coords.ra.wrap_at(180 * units.deg).radian
dec = coords.dec.radian
color_map = plt.cm.Spectral_r
fig = plt.figure(figsize=(6, 4))
fig.add_subplot(111, projection='aitoff')
image = plt.hexbin(ra, dec, cmap=color_map,
gridsize=45, mincnt=1, bins='log')
plt.xlabel('R.A.')
plt.ylabel('Decl.')
plt.grid(True)
plt.colorbar(image, spacing='uniform', extend='max')
plt.show()
Which gives
I guess your problem lies in the use of the extent which is set to something other than the range of the spherical coordinate system.
The following works fine:
import matplotlib.pyplot as plt
import numpy as np
ra = np.linspace(-np.pi/2.,np.pi/2.,1000)
dec = np.sin(ra)*np.pi/2./2.
points = np.array([ra, dec])
plt.subplot(111, projection="aitoff")
color_map = plt.cm.Spectral_r
x, y = points
gsize = 45
image = plt.hexbin(x,y,cmap=color_map,
gridsize=45,mincnt=1,bins='log')
plt.xlabel('R.A.')
plt.ylabel(r'Decl.')
plt.grid(True)
cb = plt.colorbar(image, spacing='uniform', extend='max')
plt.show()

Bigger marker size for plot using pcolormesh

I am trying to create a color mesh plot but the data points and their corresponding colors appear too small.
My script is:
import pandas as pd
import numpy as np
from mpl_toolkits.basemap import Basemap, cm
import matplotlib.pyplot as plt
df = pd.read_csv('data.csv', usecols=[1,2,4])
df = df.apply(pd.to_numeric)
val_pivot_df = df.pivot(index='Latitude', columns='Longitude', values='Bin 1')
lons = val_pivot_df.columns.astype(float)
lats = val_pivot_df.index.astype(float)
fig, ax = plt.subplots(1, figsize=(8,8))
m = Basemap(projection='merc',
llcrnrlat=df.dropna().min().Latitude-5
, urcrnrlat=df.dropna().max().Latitude+5
, llcrnrlon=df.dropna().min().Longitude-5
, urcrnrlon=df.dropna().max().Longitude+5
, resolution='i', area_thresh=10000
)
m.drawcoastlines()
m.drawstates()
m.drawcountries()
m.fillcontinents(color='gray', lake_color='white')
m.drawmapboundary(fill_color='0.3')
x, y = np.meshgrid(lons,lats)
px,py = m(x,y)
data_values = val_pivot_df.values
masked_data = np.ma.masked_invalid(data_values)
cmap = plt.cm.viridis
m.pcolormesh(px, py, masked_data, vmin=0, vmax=8000)
m.colorbar()
plt.show()
I'm looking to get the markersize larger of each data point but I can't seem to find any documentation on how to do this for pcolormesh
There is no marker in a pcolormesh. The size of the colored areas in a pcolor plot is determined by the underlying grid. As an example, if the grid in x direction was [0,1,5,105], the last column would be 100 times larger in size than the first.
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)
x = [0,1,5,25,27,100]
y = [0,10,20,64,66,100]
X,Y = np.meshgrid(x,y)
Z = np.random.rand(len(y)-1, len(x)-1)
plt.pcolormesh(X,Y,Z)
plt.show()

python: plotting a histogram with a function line on top

I'm trying to do a little bit of distribution plotting and fitting in Python using SciPy for stats and matplotlib for the plotting. I'm having good luck with some things like creating a histogram:
seed(2)
alpha=5
loc=100
beta=22
data=ss.gamma.rvs(alpha,loc=loc,scale=beta,size=5000)
myHist = hist(data, 100, normed=True)
Brilliant!
I can even take the same gamma parameters and plot the line function of the probability distribution function (after some googling):
rv = ss.gamma(5,100,22)
x = np.linspace(0,600)
h = plt.plot(x, rv.pdf(x))
How would I go about plotting the histogram myHist with the PDF line h superimposed on top of the histogram? I'm hoping this is trivial, but I have been unable to figure it out.
just put both pieces together.
import scipy.stats as ss
import numpy as np
import matplotlib.pyplot as plt
alpha, loc, beta=5, 100, 22
data=ss.gamma.rvs(alpha,loc=loc,scale=beta,size=5000)
myHist = plt.hist(data, 100, normed=True)
rv = ss.gamma(alpha,loc,beta)
x = np.linspace(0,600)
h = plt.plot(x, rv.pdf(x), lw=2)
plt.show()
to make sure you get what you want in any specific plot instance, try to create a figure object first
import scipy.stats as ss
import numpy as np
import matplotlib.pyplot as plt
# setting up the axes
fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot(111)
# now plot
alpha, loc, beta=5, 100, 22
data=ss.gamma.rvs(alpha,loc=loc,scale=beta,size=5000)
myHist = ax.hist(data, 100, normed=True)
rv = ss.gamma(alpha,loc,beta)
x = np.linspace(0,600)
h = ax.plot(x, rv.pdf(x), lw=2)
# show
plt.show()
One could be interested in plotting the distibution function of any histogram.
This can be done using seaborn kde function
import numpy as np # for random data
import pandas as pd # for convinience
import matplotlib.pyplot as plt # for graphics
import seaborn as sns # for nicer graphics
v1 = pd.Series(np.random.normal(0,10,1000), name='v1')
v2 = pd.Series(2*v1 + np.random.normal(60,15,1000), name='v2')
# plot a kernel density estimation over a stacked barchart
plt.figure()
plt.hist([v1, v2], histtype='barstacked', normed=True);
v3 = np.concatenate((v1,v2))
sns.kdeplot(v3);
plt.show()
from a coursera course on data visualization with python
Expanding on Malik's answer, and trying to stick with vanilla NumPy, SciPy and Matplotlib. I've pulled in Seaborn, but it's only used to provide nicer defaults and small visual tweaks:
import numpy as np
import scipy.stats as sps
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style='ticks')
# parameterise our distributions
d1 = sps.norm(0, 10)
d2 = sps.norm(60, 15)
# sample values from above distributions
y1 = d1.rvs(300)
y2 = d2.rvs(200)
# combine mixture
ys = np.concatenate([y1, y2])
# create new figure with size given explicitly
plt.figure(figsize=(10, 6))
# add histogram showing individual components
plt.hist([y1, y2], 31, histtype='barstacked', density=True, alpha=0.4, edgecolor='none')
# get X limits and fix them
mn, mx = plt.xlim()
plt.xlim(mn, mx)
# add our distributions to figure
x = np.linspace(mn, mx, 301)
plt.plot(x, d1.pdf(x) * (len(y1) / len(ys)), color='C0', ls='--', label='d1')
plt.plot(x, d2.pdf(x) * (len(y2) / len(ys)), color='C1', ls='--', label='d2')
# estimate Kernel Density and plot
kde = sps.gaussian_kde(ys)
plt.plot(x, kde.pdf(x), label='KDE')
# finish up
plt.legend()
plt.ylabel('Probability density')
sns.despine()
gives us the following plot:
I've tried to stick with a minimal feature set while producing relatively nice output, notably using SciPy to estimate the KDE is very easy.

Categories

Resources