Python netcdf cartopy - Plotting a selection of data - python

I have a netcdf file ('test.nc'). The variables of the netcdf file are the following:
variables(dimensions): float64 lon(lon), float64 lat(lat), int32 crs(), int16 Band1(lat,lon)
I am interested in the ´Band1´ variable.
Using cartopy, I could plot the data using the following code:
import numpy as np
import pandas as pd
import gzip
from netCDF4 import Dataset,num2date
import time
import matplotlib.pyplot as plt
import os
import matplotlib as mplt
#mplt.use('Agg')
import cartopy.crs as ccrs
import cartopy.feature as cfea
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
projection=ccrs.PlateCarree()
bbox=[-180,180,-60,85];creg='glob'
mplt.rc('xtick', labelsize=9)
mplt.rc('ytick', labelsize=9)
nc = Dataset('test.nc','r')
lat = nc.variables['lat'][:]
lon = nc.variables['lon'][:]
kopi= (nc.variables['Band1'][:,:])
nc.close()
fig=plt.figure(figsize=(11,5))
ax=fig.add_subplot(1,1,1,projection=projection)
ax.set_extent(bbox,projection)
ax.add_feature(cfea.COASTLINE,lw=.5)
ax.add_feature(cfea.RIVERS,lw=.5)
ax.add_feature(cfea.BORDERS, linewidth=0.6, edgecolor='dimgray')
ax.background_patch.set_facecolor('.9')
levels=[1,4,8,11,14,17,21,25,29]
cmap=plt.cm.BrBG
norm=mplt.colors.BoundaryNorm(levels,cmap.N)
ddlalo=.25
pc=ax.contourf(lon,lat,kopi,levels=levels,transform=projection,cmap=cmap,norm=norm,extend='both')
divider = make_axes_locatable(ax)
ax_cb = divider.new_horizontal(size="3%", pad=0.1, axes_class=plt.Axes)
fig.colorbar(pc,extend='both', cax=ax_cb)
fig.add_axes(ax_cb)
fig.colorbar(pc,extend='both', cax=ax_cb)
ttitle='Jony'
ax.set_title(ttitle,loc='left',fontsize=9)
plt.show()
However, I would like just to plot a selection of values inside the variable ´Band1´. I thought I could use the following code:
kopi= (nc.variables['Band1'][:,:])<=3
However it does not work and instead of plotting the area corresponding to the value selection it selected the all map.
How could I select and plot a desired range of values inside the variables ´Band1´?

Just mask the values with np.nan
kopi[kopi <=3] = np.nan
This should yield to white pixels in your plot.
Please provide test data in the future.

Related

Creating scatter plot

Can someone help me with how to create a scatterplot. I have written the following code, however, it is not the scatter plot link that I expected as all data only concentrate 3 values of x-variable
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.linear_model import LinearRegression
from scipy.stats import skew
from warnings import filterwarnings
filterwarnings('ignore')
df_transactions = pd.read_csv('transactions.csv')
daily_revenue= df_transactions.groupby("days_after_open").sum()['revenue']
df_transactions["daily_revenue"] = daily_revenue
x = df_transactions["days_after_open"]
y = df_transactions["daily_revenue"]
plt.scatter(x,y,alpha=0.2)
plt.xlabel("Days After Open (days)")
plt.ylabel("Daily Reveue ($)")
plt.savefig("plot")
dataframe image
Please define the 'daily_revenue' following before moving to the scatter plot.
y = df_transactions["daily_revenue"]

How to print the heatmap in a square shape using seaborn?

When I run the code below I notice that the heatmap does not have a square shape knowing that I have used square=True but it did not work! Any idea how can I print the heatmap in a square format? Thank you!
The code:
from datetime import datetime
import numpy as np
import pandas as pd
import matplotlib as plt
import os
import seaborn as sns
temp_hourly_A5_A7_AX_ASHRAE=pd.read_csv('C:\\Users\\cvaa4\\Desktop\\projects\\s\\temp_hourly_A5_A7_AX_ASHRAE.csv',index_col=0, parse_dates=True, dayfirst=True, skiprows=2)
sns.heatmap(temp_hourly_A5_A7_AX_ASHRAE,cmap="YlGnBu", vmin=18, vmax=27, square=True, cbar=False, linewidth=0.0001);
The result:
square=True should work to have square cells, below is a working example:
import pandas as pd
import numpy as np
import seaborn as sns
df = pd.DataFrame(np.tile([0,1], 15*15).reshape(-1,15))
sns.heatmap(df, square=True)
If you want a square shape of the plot however, you can use set_aspect and the shape of the data:
ax = sns.heatmap(df)
ax.set_aspect(df.shape[1]/df.shape[0]) # here 0.5 Y/X ratio
You can use matplotlib and set a figsize before plotting heatmap.
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
rnd = np.random.default_rng(12345)
data = rnd.uniform(-100, 100, [100, 50])
plt.figure(figsize=(6, 5))
sns.heatmap(data, cmap='viridis');
Note that I used figsize=(6, 5) rather than a square figsize=(5, 5). This is because on a given figsize, seaborn also puts the colorbar, which might cause the heatmap to be squished a bit. You might want to change those figsizes too depending on what you need.

Extracting data from cartopy.feature

how can I extract contour lines from data imported through cartopy's feature interface? If the solution involves geoviews.feature or another wrapper, that is OK, of course.
For instance, how would I extract the data plotted as cfeature.COASTLINE in the following example?
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
ax = plt.axes(projection=ccrs.PlateCarree())
ax.add_feature(cfeature.COASTLINE)
plt.show()
I'm grateful for any hints you might have!
FWIW, in basemap, I would do it like this:
import mpl_toolkits.basemap as bm
import matplotlib.pyplot as plt
m = bm.Basemap(width=2000e3,height=2000e3,
resolution='l',projection='stere',
lat_ts=70,lat_0=70,lon_0=-60.)
fig,ax=plt.subplots()
coastlines = m.drawcoastlines().get_segments()
You can get the coordinates for the plotted lines directly from the feature, which contains a set of shapely.MultiLineStrings. As a proof of concept, check out this code:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
fig, (ax1,ax2) = plt.subplots(nrows=2, subplot_kw = dict(projection=ccrs.PlateCarree()))
ax1.add_feature(cfeature.COASTLINE)
for geom in cfeature.COASTLINE.geometries():
for g in geom.geoms:
print(list(g.coords))
ax2.plot(*zip(*list(g.coords)))
plt.show()
which gives this picture:
In other words, you can iterate over the MultiLineStrings of the feature by accessing its geometries(). Each of these MultiLineStrings then contains one or more LineStrings, which have a coords attribute that can be converted into a list. Hope this helps.
For future reference: Some time later, I also came across this (more general?) method to access any feature:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader
shpfilename = shpreader.natural_earth(resolution='110m',
category='physical',
name='coastline')
coastlines = shpreader.Reader(shpfilename).records()
fig, ax = plt.subplots(subplot_kw = dict(projection=ccrs.PlateCarree()))
for c in coastlines:
for g in c.geometry:
ax.plot(*zip(*list(g.coords)))
yielding the same plot as above.

Matplotlib: Creating a colorbar based on datetime module for a series of lines in a plot

I'm trying to color code a series of lines in a plot based on the python module datetime. I've tried mapping the the datetime data (as a numpy array) to RGBA using ScalarMappable; however, I'm running into difficulties. Please find a segment of the code below:
import datetime as dt
import matplotlib.pyplot as plt
import matplotlib.cm as mplcm
import matplotlib.colors as colors
clmap = 'jet'
cm = plt.get_cmap(clmap)
iDT = dt.datetime(2012,1,1,0,0,0)
fDT = dt.datetime(2012,1,2,0,0,0)
cNorm = colors.Normalize( vmin=iDT, vmax=fDT )
scalarMap = mplcm.ScalarMappable( norm=cNorm, cmap=cm )
scalarMap.set_array(retDays)
fig,ax = plt.subplots()
ax.set_color_cycle( [scalarMap.to_rgba(x) for x in retDays] )
Where retDays is a numpy array of datetime values.
I get the following error when using set_color_cycle:
ValueError: setting an array element with a sequence.
Your help is greatly appreciated.

forming histogram plots in python

suppose I want to plot 2 histogram subplots on the same window in python, one below the next. The data from these histograms will be read from a file containing a table with attributes A and B.
In the same window, I need a plot of A vs the number of each A and a plot of B vs the number of each B - directly below the plot of A. so suppose the attributes were height and weight, then we'd have a graph of height and number of people with said height and below it a separate graph of weight and number of people with said weight.
import numpy as np; import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
frame = pd.read_csv('data.data', header=None)
subplot.hist(frame['A'], frame['A.count()'])
subplot.hist(frame['B'], frame['B.count()'])
Thanks for any help!
Using pandas you can make histograms like this:
import numpy as np; import pandas as pd
import matplotlib.pyplot as plt
frame = pd.read_csv('data.csv')
frame.hist(layout = (2,1))
plt.show()
I'm confused by the second part of the question. Do you want four separate subplots?
You can do this:
import numpy as np
import numpy.random
import pandas as pd
import matplotlib.pyplot as plt
#df = pd.read_csv('data.data', header=None)
df = pd.DataFrame({'A': numpy.random.random_integers(0,10,30),
'B': numpy.random.random_integers(0,10,30)})
print df['A']
ax1 = plt.subplot(211)
ax1.set_title('A')
ax1.set_ylabel('number of people')
ax1.set_xlabel('height')
ax2 = plt.subplot(212)
ax2.set_title('B')
ax2.set_ylabel('number of people')
ax2.set_xlabel('weight')
ax1.hist(df['A'])
ax2.hist(df['B'])
plt.tight_layout()
plt.show()

Categories