I have to confess I still have problems understanding the proper setup and relation of the plots and the parts of it with matplotlib, is still confusing how fig with plt with ax relates each other so I just has gone trial and error, docs are sometimes more confusing to me. :-(
I am plotting weather values, from a json and got points. that I can plot with the following code like the image below
fig=plt.figure(figsize=(10,8))
ax=fig.add_subplot(1,1,1,projection=mapcrs)
ax.set_extent([-93,-86,13,19],datacrs)
ax.add_feature(cfeature.COASTLINE)
ax.add_feature(cfeature.BORDERS, linestyle=':')
ax.scatter(lon,lat,c=dat,transform=datacrs)
and I am able to plot the map
Then I generate interpolation using metpy with this code
gridx, gridy, gridz = interpolate_to_grid(lon, lat, dat, interp_type='rbf', hres=.1, rbf_func='linear', rbf_smooth=0)
fig=plt.figure(figsize=(15,15))
ax=fig.add_subplot(1,1,1,projection=mapcrs)
#ax = fig.add_axes([0, 0, 1, 1], projection=mapcrs)
#ax.set_extent([-93,-86,13,19])
#ax.add_feature(cfeature.COASTLINE)
#ax.add_feature(cfeature.BORDERS, linestyle=':')
ax.contourf(gridx,gridy,gridz,levels=np.arange(10,60,2),cmap='viridis')
plt.plot(lon,lat,'k.',color='white')
I got the interpolation of points as desired but cannot show the features, how is the way to do it? If I uncomment the ax.extent all I see is an empty white figure. If I uncomment the ax.features the interpolation show as the below image but not the map.
thanks for any help and guidance.
You are missing the transform keyword argument in the contourf function in order to give the coordinate system of the interpolated data. Here is a minimal working example with random data, with the obtained output below:
import numpy as np
from cartopy import crs, feature
from matplotlib import pyplot as plt
from scipy.interpolate import griddata
# figure
fig = plt.figure(figsize=(5, 5))
# coordinate systems
crs_map = crs.Mercator()
crs_data = crs.PlateCarree()
# random data
np.random.seed(42) # for repro.
n = 100
lon = -89 + 2 * np.random.randn(n)
lat = 16 + 2 * np.random.randn(n)
dat = np.random.rand(n)
# interpolated data
ilon = np.linspace(-93, -86, 200)
ilat = np.linspace(13, 19, 200)
ilon, ilat = np.meshgrid(ilon, ilat)
idat = griddata((lon, lat), dat, (ilon, ilat), method="linear")
# show up
ax = fig.add_subplot(1, 1, 1, projection=crs_map)
ax.set_extent([-93, -86, 13, 19], crs_data)
ax.add_feature(feature.COASTLINE)
ax.add_feature(feature.BORDERS, ls=":", lw=0.5)
ax.scatter(lon, lat, c=dat, transform=crs_data) # this is invisible with contour
ax.plot(lon, lat, "k.", transform=crs_data) # in order to see the points
ax.contourf(ilon, ilat, idat, levels=np.linspace(0, 1, 10), transform=crs_data)
Related
I have a 3-dimensional xarray DataArray of changes in surface temperature with coordinates of time, lat and lon. I am visualizing the data using Cartopy. You can find the 125 MB file here.
While producing plots of time-averages over different periods, I've found that I'm unable to produce orthographic projections when including certain time steps, such as the 132nd (index 131) time. Here is a plot of the time average from 0 to 130:
But this happens when I instead perform the time average from 0 to 131:
Here is the code I used to produce the plots:
# import statements
import cartopy.crs as ccrs
import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
from cartopy.util import add_cyclic_point
%matplotlib inline
%config InlineBackend.figure_format = "jpg"
# read in data
ens_mean = xr.open_dataarray('temp_changes_ens_mean.nc')
# time average subset of data
to_plot = ens_mean.isel(time=slice(None,131)).mean(dim='time') # change 130 to 131 to break cartopy
# add cyclic point to avoid white lines
data = to_plot
lon = to_plot.coords['lon']
lon_idx = data.dims.index('lon')
wrap_data, wrap_lon = add_cyclic_point(data.values, coord=lon, axis=lon_idx)
# make an orthographic plot centered on north pole
fig = plt.figure(figsize=(4.5,3.5))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.Orthographic(0, 90))
ax.coastlines()
im = ax.contourf(wrap_lon, to_plot.lat, wrap_data,
transform=ccrs.PlateCarree())
# add colorbar
cb = fig.colorbar(im,orientation='horizontal',shrink=0.5,pad=0.05)
cb.ax.tick_params(labelsize=8)
cb.set_label('ΔSAT (K)',fontsize=8)
plt.tight_layout(w_pad=0.05)
plt.show()
This occurs whether I add a cyclic point or not. I am able to make quick plots of the data using matplotlib or xarray's built-in plotting without error. I've already checked for NaN values in the data. Lastly, if I remove the transform argument in the contourf line, it is able to produce a coherent plot, which leads me to think it is the transformation step that produces this odd plot.
Thanks for the help!
You can use ax.set_global() method to reset the coordinate limits:
#!/usr/bin/env ipython
# --------------------------------------------
import cartopy.crs as ccrs
import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
from cartopy.util import add_cyclic_point
# --------------------------------------------------------------------------------------
#%matplotlib inline
#%config InlineBackend.figure_format = "jpg"
# read in data
ens_mean = xr.open_dataarray('temp_changes_ens_mean.nc')
# time average subset of data
to_plot = ens_mean.isel(time=slice(None,131)).mean(dim='time') # change 130 to 131 to break cartopy
# add cyclic point to avoid white lines
data = to_plot
lon = to_plot.coords['lon']
lon_idx = data.dims.index('lon')
wrap_data, wrap_lon = add_cyclic_point(data.values, coord=lon, axis=lon_idx)
# ------------------------------------------------------------------
# this is not working:
xlims = (np.min(ens_mean['lon']),np.max(ens_mean['lon']));
ylims = (np.min(ens_mean['lat']),np.max(ens_mean['lat']));
# ------------------------------------------------------------------
lon = to_plot.coords['lon']
# ====================================================================================
# make an orthographic plot centered on north pole
# Let us make a working/satisfying plot:
fig = plt.figure(figsize=(4.5,3.5))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.Orthographic(0, 90))
ax.coastlines()
im = ax.contourf(wrap_lon, to_plot.lat, wrap_data,
transform=ccrs.PlateCarree())
# -----------------------------------------------------------
# add colorbar
cb = fig.colorbar(im,orientation='horizontal',shrink=0.5,pad=0.05)
cb.ax.tick_params(labelsize=8)
cb.set_label('ΔSAT (K)',fontsize=8)
plt.tight_layout(w_pad=0.05)
ax.set_global();
#ax.set_xlim(xlims);
#ax.set_ylim(ylims);
plt.show()
I am trying to plot some latitude and longitudes on the map of delhi which I am able to do by using a shape file in python3.8 using geopandas
Here is the link for the shape file:
https://drive.google.com/file/d/1CEScjlcsKFCgdlME21buexHxjCbkb3WE/view?usp=sharing
Following is my code to plot points on the map:
lo=[list of longitudes]
la=[list of latitudes]
delhi_map = gpd.read_file(r'C:\Users\Desktop\Delhi_Wards.shp')
fig,ax = plt.subplots(figsize = (15,15))
delhi_map.plot(ax = ax)
geometry = [Point(xy) for xy in zip(lo,la)]
geo_df = gpd.GeoDataFrame(geometry = geometry)
print(geo_df)
g = geo_df.plot(ax = ax, markersize = 20, color = 'red',marker = '*',label = 'Delhi')
plt.show()
Following is the result:
Now this map is not very clear and anyone will not be able to recognise the places marked so i tried to use basemap for a more detailed map through the following code:
df = gpd.read_file(r'C:\Users\Jojo\Desktop\Delhi_Wards.shp')
new_df = df.to_crs(epsg=3857)
print(df.crs)
print(new_df.crs)
ax = new_df.plot()
ctx.add_basemap(ax)
plt.show()
And following is the result:
I am getting the basemap but my shapefile is overlapping it. Can i get a map to plot my latitudes and longitudes where the map is much more detailed with names of places or roads or anything similar to it like in google maps or even something like the map which is being overlapped by the blue shapefile map?
Is it possible to plot on a map like this??
https://www.researchgate.net/profile/P_Jops/publication/324715366/figure/fig3/AS:618748771835906#1524532611545/Map-of-Delhi-reproduced-from-Google-Maps-12.png
use zorder parameter to adjust the layers' orders (lower zorder means lower layer), and alpha to the polygon. anyway, I guess, you're plotting df twice, that's why it's overlapping.
here's my script and the result
import geopandas as gpd
import matplotlib.pyplot as plt
import contextily as ctx
from shapely.geometry import Point
long =[77.2885437011719, 77.231931, 77.198767, 77.2750396728516]
lat = [28.6877899169922, 28.663863, 28.648287, 28.5429172515869]
geometry = [Point(xy) for xy in zip(long,lat)]
wardlink = "New Folder/wards delimited.shp"
ward = gpd.read_file(wardlink, bbox=None, mask=None, rows=None)
geo_df = gpd.GeoDataFrame(geometry = geometry)
ward.crs = {'init':"epsg:4326"}
geo_df.crs = {'init':"epsg:4326"}
# plot the polygon
ax = ward.plot(alpha=0.35, color='#d66058', zorder=1)
# plot the boundary only (without fill), just uncomment
#ax = gpd.GeoSeries(ward.to_crs(epsg=3857)['geometry'].unary_union).boundary.plot(ax=ax, alpha=0.5, color="#ed2518",zorder=2)
ax = gpd.GeoSeries(ward['geometry'].unary_union).boundary.plot(ax=ax, alpha=0.5, color="#ed2518",zorder=2)
# plot the marker
ax = geo_df.plot(ax = ax, markersize = 20, color = 'red',marker = '*',label = 'Delhi', zorder=3)
ctx.add_basemap(ax, crs=geo_df.crs.to_string(), source=ctx.providers.OpenStreetMap.Mapnik)
plt.show()
I don't know about google maps being in the contextily, I don't think it's available. alternatively, you can use OpenStreetMap base map which shows quite the same toponym, or any other basemap you can explore. use `source` keyword in the argument, for example, `ctx.add_basemap(ax, source=ctx.providers.OpenStreetMap.Mapnik)` . here's how to check the available providers and the map each providers provides:
>>> ctx.providers.keys()
dict_keys(['OpenStreetMap', 'OpenSeaMap', 'OpenPtMap', 'OpenTopoMap', 'OpenRailwayMap', 'OpenFireMap', 'SafeCast', 'Thunderforest', 'OpenMapSurfer', 'Hydda', 'MapBox', 'Stamen', 'Esri', 'OpenWeatherMap', 'HERE', 'FreeMapSK', 'MtbMap', 'CartoDB', 'HikeBike', 'BasemapAT', 'nlmaps', 'NASAGIBS', 'NLS', 'JusticeMap', 'Wikimedia', 'GeoportailFrance', 'OneMapSG'])
>>> ctx.providers.OpenStreetMap.keys()
dict_keys(['Mapnik', 'DE', 'CH', 'France', 'HOT', 'BZH'])
I don't know geopandas. The idea I'm suggesting uses only basic python and matplotlib. I hope you can adapt it to your needs.
The background is the following map. I figured out the GPS coordinates of its corners using google-maps.
The code follows the three points of my remark. Note that the use of imread and imshow reverses the y coordinate. This is why the function coordinatesOnFigur looks non-symmetrical in x and y.
Running the code yields the map with a red bullet near Montijo (there is a small test at the end).
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib import patches
from matplotlib.widgets import Button
NE = (-8.9551, 38.8799)
SE = (-8.9551, 38.6149)
SW = (-9.4068, 38.6149)
NW = (-9.4068, 38.8799)
fig = plt.figure(figsize=(8, 6))
axes = fig.add_subplot(1,1,1, aspect='equal')
img_array = plt.imread("lisbon_2.jpg")
axes.imshow(img_array)
xmax = axes.get_xlim()[1]
ymin = axes.get_ylim()[0] # the y coordinates are reversed, ymax=0
# print(axes.get_xlim(), xmax)
# print(axes.get_ylim(), ymin)
def coordinatesOnFigure(long, lat, SW=SW, NE=NE, xmax=xmax, ymin=ymin):
px = xmax/(NE[0]-SW[0])
qx = -SW[0]*xmax/(NE[0]-SW[0])
py = -ymin/(NE[1]-SW[1])
qy = NE[1]*ymin/(NE[1]-SW[1])
return px*long + qx, py*lat + qy
# plotting a red bullet that corresponds to a GPS location on the map
x, y = coordinatesOnFigure(-9, 38.7)
print("test: on -9, 38.7 we get", x, y)
axes.scatter(x, y, s=40, c='red', alpha=0.9)
plt.show()
I've obtained a shapefile of zipcode perimeters from here and would like to plot them on top of a Cartopy map, as I did in this example.
According to the source, this data is in EPSG 4326 coordinate system. When I attempt to plot the data
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.io.img_tiles as cimgt
from cartopy.io.shapereader import Reader
from cartopy.feature import ShapelyFeature
# Create a Stamen terrain background instance
stamen_terrain = cimgt.Stamen('terrain-background')
fig = plt.figure(figsize = (mapsize,mapsize))
ax = fig.add_subplot(1, 1, 1, projection=stamen_terrain.crs)
# Set range of map, stipulate zoom level
ax.set_extent([-122.7, -121.5, 37.15, 38.15], crs=ccrs.Geodetic())
ax.add_image(stamen_terrain, 8, zorder = 0)
# Add city borders
shape_feature = ShapelyFeature(Reader(shapefile).geometries(), ccrs.epsg(4326),
linewidth = 2, facecolor = (1, 1, 1, 0),
edgecolor = (0.3, 0.3, 0.3, 1))
ax.add_feature(shape_feature, zorder = 1)
I see the following error:
ValueError: EPSG code does not define a projection
Probably related -- when I look at the ccrs.epsg() function, it says that this EPSG code is not supported
help(ccrs.epsg)
Help on function epsg in module cartopy.crs:
epsg(code)
Return the projection which corresponds to the given EPSG code.
The EPSG code must correspond to a "projected coordinate system",
so EPSG codes such as 4326 (WGS-84) which define a "geodetic coordinate
system" will not work.
Note
----
The conversion is performed by querying https://epsg.io/ so a
live internet connection is required.
Given this result, I also tried using ccrs.Geodetic():
# Add city borders
shape_feature = ShapelyFeature(Reader(shapefile).geometries(), ccrs.Geodetic(),
linewidth = 2, facecolor = (1, 1, 1, 0),
edgecolor = (0.3, 0.3, 0.3, 1))
ax.add_feature(shape_feature, zorder = 1)
But this also fails to show the zipcode perimeters, and shows this warning message:
UserWarning: Approximating coordinate system <cartopy._crs.Geodetic object at 0x1a2d2375c8> with the PlateCarree projection.
'PlateCarree projection.'.format(crs))
I've tried ccrs.PlateCarree() too, but no luck. Please help!
To plot data from different sources together, one must declare correct coordinate reference system for each data set. In the case of shapefile, you can find it in its accompanying xxx.prj file.
Here is the working code:
import cartopy.io.img_tiles as cimgt
from cartopy.io.shapereader import Reader
from cartopy.feature import ShapelyFeature
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
shapefile_name= "./data/ZIPCODE.shp"
mapwidth, mapheight = 8, 8
pad = 0.25
stamen_terrain = cimgt.Stamen('terrain-background')
stm_crs = stamen_terrain.crs
fig = plt.figure(figsize = (mapwidth, mapheight))
ax = fig.add_subplot(1, 1, 1, projection=stm_crs) #world mercator
# Set extent of map
ax.set_extent([-123.3-pad, -121.5+pad, 37.05-pad, 38.75+pad], crs=ccrs.Geodetic())
# Plot base map
ax.add_image(stamen_terrain, 8, zorder=0)
# Add polygons from shapefile
# Note: the use of `ccrs.epsg(26910)`
shape_feature = ShapelyFeature(Reader(shapefile_name).geometries(), ccrs.epsg(26910))
# You can choose one of the 2 possible methods to plot
# ... the geometries from shapefile
# Styling is done here.
method = 1
if method==1:
# iteration is hidden
ax.add_feature(shape_feature, facecolor='b', edgecolor='red', alpha=0.4, zorder = 15)
if method==2:
# iterate and use `.add_geometries()`
# more flexible to manipulate particular items
for geom in shape_feature.geometries():
ax.add_geometries([geom], crs=shape_feature.crs, facecolor='b', edgecolor='red', alpha=0.4)
plt.show()
The output plot:
When plotting with Basemap's readshapefile, if the defined map is centered anywhere else than the longitudinal center of the shapefile, only a portion of it it's plotted. Here's an example using Natural Earth's coastlines:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
shpf = './NaturalEarth/ne_50m_land/ne_50m_land'
fig, ax = plt.subplots(nrows=1, ncols=1, dpi=100)
m = Basemap(
ax = ax,
projection = 'cyl',
llcrnrlon = 0, llcrnrlat = -90,
urcrnrlon = 360, urcrnrlat = 90
)
m.readshapefile(shpf,'ne_50m_land')
m.drawmeridians(np.arange(0,360,45),labels=[True,False,False,True])
Which produces:
Is there a workaround for this with Basemap or Python? I know some people re-center the shapefile in QGIS or similar, but it seems unpractical to do so every time you create a new map, and my QGIS skills are extremely basic.
One way to do it would be to tell readshapefile not to plot the coastlines directly and then to manipulate the line segments before plotting them yourself. Here an example based on your use case:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
shpf = 'shapefiles/ne_50m_land'
fig, ax = plt.subplots(nrows=1, ncols=1, dpi=100)
m = Basemap(
ax = ax,
projection = 'cyl',
llcrnrlon = 0, llcrnrlat = -90,
urcrnrlon = 360, urcrnrlat = 90
)
m.readshapefile(shpf,'ne_50m_land', drawbounds = False)
boundary = 0.0
for info, shape in zip(m.ne_50m_land_info, m.ne_50m_land):
lons, lats = map(np.array, zip(*shape))
sep = (lons <= boundary).astype(int)
roots = np.where(sep[:-1]+sep[1:] == 1)[0]+1
lower = np.concatenate([[0],roots]).astype(int)
upper = np.concatenate([roots,[len(lons)]]).astype(int)
for low, high in zip(lower,upper):
lo_patch = lons[low:high]
la_patch = lats[low:high]
lo_patch[lo_patch<0] += 360
x,y = m(lo_patch,la_patch)
ax.plot(x,y,'k',lw=0.5)
m.drawmeridians(np.arange(0,360,45),labels=[True,False,False,True])
plt.show()
In the example above, I iterate through the line segments of the shape file the way it is explained in the Basemap documentation. First I thought it would be enough to just add 360 to each point with a longitude smaller 0, but then you would get horizontal lines whenever a coast line crosses the 0 degree line. So, instead, one has to cut the lines into smaller segments whenever such a crossing appears. This is quite easily accomplished with numpy. I then use the plot command to draw the coast lines. If you want to do something more complex have a look at the Basemap documentation.
The final result looks like this:
Hope this helps.
OMI (Ozone Monitoring Instrument) measures the key air quality components such as nitrogen dioxide(NO2), ozone(O3). The daily columnO3 file which I downloaded here represented the global distribution of ozone column concentration of troposphere.
The file's size is about 90Mb. Anyone interested can download any of them.
The data was uploaded here in the shape of (15, 720, 1440)
15 is the Number of candidate scenes
1440 is the X-dimension, longitudes [-180:180] from left to right
720 is the Y-dimension, latitudes [-90:90] from bottom to top
Wiht h5py and matplotlib.basemap, here is my attempt:
import h5py
import numpy as np
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import sys
file = h5py.File("OMI-Aura_L2-OMNO2_2016m0529t1759-o63150_v003-2016m0531t023832.he5", 'r')
dataFields=file['HDFEOS']['GRIDS']['ColumnAmountNO2']['Data Fields']
SDS_NAME='ColumnAmountNO2'
data=dataFields[SDS_NAME]
map_label=data.attrs['Units'].decode()
fv=data.attrs['_FillValue']
mv=data.attrs['MissingValue']
offset=data.attrs['Offset']
scale=data.attrs['ScaleFactor']
lat=dataFields['Latitude'][:][0]
min_lat=np.min(lat)
max_lat=np.max(lat)
lon=dataFields['Longitude'][:][0]
min_lon=np.min(lon)
max_lon=np.max(lon)
dataArray=data[:][1]
dataArray[dataArray==fv]=np.nan
dataArray[dataArray==mv]=np.nan
dataArray = scale * (dataArray - offset)
fig = plt.figure()
data_mask = np.ma.masked_array(data[0], np.isnan(data[0]))
m = Basemap(projection='cyl', resolution='l',llcrnrlat=-90, urcrnrlat = 90,llcrnrlon=-180, urcrnrlon = 180)
m.drawcoastlines(linewidth=0.5)
m.drawparallels(np.arange(-90., 120., 30.), labels=[1, 0, 0, 0])
m.drawmeridians(np.arange(-180, 180., 45.), labels=[0, 0, 0, 1])
my_cmap = plt.cm.get_cmap('gist_stern_r')
my_cmap.set_under('w')
m.pcolormesh(lon, lat, data_mask,latlon=True, cmap=my_cmap)
cb = m.colorbar()
cb.set_label(map_label)
plt.autoscale()
plt.show()
Figure shows like this:
Using Panoply, with candidate 0, figure shows like this:
My question
How to set the candidate scenes to represent the global distribution daily(What is the meaning of candidate scenes? Does it correspond to orbit tracks?)
What's wrong with my code which not showing the correct figure
My target
The figure below was clipped from Internet. That's my target style!
Any advice or tutorial guide would be appreciate!
The Latitude and Longitude variables have missing values too, which are -1.2676506e+30 and thus cause the large xrange and yrange in your plots. Also, note that the _FillValue and MissingValue attributes are lists, so your replacement with NaNs went wrong.
import h5py
import numpy as np
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import sys
def array_with_nans(h5var):
""" Extracts the array and replaces fillvalues and missing values with Nans
"""
array = h5var[:] # not very efficient
# _FillValue and MissingValue attributes are lists
for value in h5var.attrs['MissingValue']:
array[array==value]=np.nan
for value in h5var.attrs['_FillValue']:
array[array==value]=np.nan
return array
#file = h5py.File("OMI-Aura_L2-OMNO2_2016m0529t1759-o63150_v003-2016m0531t023832.he5", 'r')
file = h5py.File("OMI-Aura_L2G-OMNO2G_2004m1001_v003-2012m0714t175148.he5", 'r')
dataFields=file['HDFEOS']['GRIDS']['ColumnAmountNO2']['Data Fields']
SDS_NAME='ColumnAmountNO2'
data=dataFields[SDS_NAME]
map_label=data.attrs['Units'].decode()
offset=data.attrs['Offset'][0]
print("offset: {}".format(offset))
scale=data.attrs['ScaleFactor'][0]
print("scale: {}".format(scale))
candidate = 0
dataArray=array_with_nans(data)[candidate]
dataArray = scale * (dataArray - offset)
lat = array_with_nans(dataFields['Latitude'])[candidate]
lon = array_with_nans(dataFields['Longitude'])[candidate]
fig = plt.figure()
data_mask = np.ma.masked_array(dataArray, np.isnan(dataArray))
m = Basemap(projection='cyl', resolution='l',llcrnrlat=-90, urcrnrlat = 90,llcrnrlon=-180, urcrnrlon = 180)
m.drawcoastlines(linewidth=0.5)
m.drawparallels(np.arange(-90., 120., 30.), labels=[1, 0, 0, 0])
m.drawmeridians(np.arange(-180, 180., 45.), labels=[0, 0, 0, 1])
my_cmap = plt.cm.get_cmap('gist_stern_r')
my_cmap.set_under('w')
m.pcolormesh(lon, lat, data_mask,latlon=True, cmap=my_cmap)
cb = m.colorbar()
cb.set_label(map_label)
plt.autoscale()
plt.show()
It's better to ask only one question per post and you are unlikely to get an answer on what the candidate scene means. You may find an answer to this in the product documentation