在使用Matplotlib和Cartopy进行正交投影绘图的过程中

huangapple go评论60阅读模式
英文:

Plotting data in orthographic projection using matplotlib & cartopy

问题

I don't know how to get a map like the attached example but without coastlines, borders and gridlines outside plotted data.
The second question is, instead of a square frame with lon and lats labels, is it possible to set the x and y axis along the plotted data outline, so that the labels are next to this outline, and not next to the frame?

import xarray as xr
from matplotlib import pyplot as plt
import cartopy.crs as ccrs
import cartopy

ds = xr.open_dataset(r'D:\Python\qq_z1000.nc')
ds2 = ds['qq'].mean(dim='time')
minn = ds2.min()
maxx = ds2.max()

fig = plt.figure(figsize=(8, 8), dpi=300, num="False")
central_lon, central_lat = 12.5, 47.5
extent = [-22.5, 45, 25, 65]
ax = plt.axes(projection=ccrs.Orthographic(central_lon, central_lat))
ax.set_extent(extent)

gl = ax.gridlines(draw_labels=True, linestyle='--', color='grey', dms=True, 
                  x_inline=False, y_inline=False, linewidth=0.3)
gl.top_labels = False
gl.right_labels = False
gl.xlabel_style = {'size': 10, 'color': 'black'}
gl.ylabel_style = {'size': 10, 'color': 'black'}
gl.xlocator = plt.FixedLocator(range(-180, 181, 10))

ax.coastlines(resolution='50m')
ax.add_feature(cartopy.feature.BORDERS, edgecolor='black')
im = ax.pcolormesh(ds2.longitude, ds2.latitude, ds2, transform=ccrs.PlateCarree(), 
                   cmap='jet', vmin=minn, vmax=maxx)

cbar = fig.colorbar(im, orientation='horizontal', pad=0.05, shrink=0.8)

#plt.savefig('my_map2.jpg', dpi=300, bbox_inches='tight')
plt.show()

在使用Matplotlib和Cartopy进行正交投影绘图的过程中

I've tried changing this line in the code in different ways, but to no avail.

im = ax.pcolormesh(ds2.longitude, ds2.latitude, ds2, transform=ccrs.PlateCarree(), cmap='jet', vmin=minn, vmax=maxx)
1: https://i.stack.imgur.com/99V5r.jpg

英文:

I don't know how to get a map like the attached example but without coastlines, borders and gridlines outside plotted data.
The second question is, instead of a square frame with lon and lats labels, is it possible to set the x and y axis along the plotted data outline, so that the labels are next to this outline, and not next to the frame?

import xarray as xr
from matplotlib import pyplot as plt
import cartopy.crs as ccrs
import cartopy

ds = xr.open_dataset(r'D:\Python\qq_z1000.nc')
ds2 = ds['qq'].mean(dim='time')
minn = ds2.min()
maxx = ds2.max()

fig = plt.figure(figsize=(8, 8), dpi=300, num="False")
central_lon, central_lat = 12.5, 47.5
extent = [-22.5, 45, 25, 65]
ax = plt.axes(projection=ccrs.Orthographic(central_lon, central_lat))
ax.set_extent(extent)

gl = ax.gridlines(draw_labels=True, linestyle='--', color='grey', dms=True, 
                  x_inline=False, y_inline=False, linewidth=0.3)
gl.top_labels = False
gl.right_labels = False
gl.xlabel_style = {'size': 10, 'color': 'black'}
gl.ylabel_style = {'size': 10, 'color': 'black'}
gl.xlocator = plt.FixedLocator(range(-180, 181, 10))

ax.coastlines(resolution='50m')
ax.add_feature(cartopy.feature.BORDERS, edgecolor='black')
im = ax.pcolormesh(ds2.longitude, ds2.latitude, ds2, transform=ccrs.PlateCarree(), 
                   cmap='jet', vmin=minn, vmax=maxx)

cbar = fig.colorbar(im, orientation='horizontal', pad=0.05, shrink=0.8)

#plt.savefig('my_map2.jpg', dpi=300, bbox_inches='tight')
plt.show()

在使用Matplotlib和Cartopy进行正交投影绘图的过程中

I've tried changing this line in the code in different ways, but to no avail.

im = ax.pcolormesh(ds2.longitude, ds2.latitude, ds2, transform=ccrs.PlateCarree(),
cmap='jet', vmin=minn, vmax=maxx)

答案1

得分: 0

我成功修正了代码以获得我想要的地图。

import matplotlib.pyplot as plt
import cartopy
import cartopy.crs as ccrs
import numpy as np
import xarray as xr
import matplotlib.path as mpath

ds = xr.open_dataset(r'R:\Python\qnew_1000.nc')
ds2 = ds['qq'].mean(dim='time')
minn = ds2.min()
maxx = ds2.max()

noProj = ccrs.PlateCarree()
myProj = ccrs.LambertConformal(central_longitude=0, central_latitude=55)
myProj._threshold = myProj._threshold/20.

plt.figure(figsize=(8,8))
axs = plt.axes(projection=myProj)

[axs_hdl] = axs.plot([60, -60, -60, 60, 60], [20, 20, 85, 85, 20],
         color='black', linewidth=0.5, marker='none',
         transform=noProj)

tx_path = axs_hdl._get_transformed_path()
path_in_data_coords, _ = tx_path.get_transformed_path_and_affine()

polygon = mpath.Path(path_in_data_coords.vertices)
axs.set_boundary(polygon) #This masks-out unwanted part of the plot
axs.set_xmargin(0)
axs.set_ymargin(0)
axs.set_global()
axs.add_feature(cartopy.feature.OCEAN, linewidth=.3, color='lightblue')
axs add_feature(cartopy.feature.LAND, zorder=1, edgecolor='black')
axs.add_feature(cartopy.feature.COASTLINE, linewidth=0.5)
axs.add_feature(cartopy.feature.BORDERS, linewidth=0.5)
axs.set_extent([-60, 60, 20, 85], crs=noProj)
axs.tick_params(axis='both', which='major', labelsize=10)
axs.set_title("")
gl=axs.gridlines(draw_labels=True, x_inline=False, y_inline=False, color='k', linestyle='dashed', linewidth=0.5)
gl.top_labels = False

pcm = axs.pcolormesh(ds2.longitude, ds2.latitude, ds2, transform=ccrs.PlateCarree(), 
                     vmin=minn, vmax=maxx, cmap='jet',
                     shading='nearest')

cbar = plt.colorbar(pcm, ax=axs, orientation='horizontal', pad=0.08, shrink=0.8)
cbar.set_label('(g kg$^{-1}$)')

plt.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.95, wspace=0.2, hspace=0.2)
plt.savefig("figure.jpg", dpi=300, bbox_inches='tight', pad_inches=0.1, format='jpg', facecolor="w", transparent=False)
plt.show()

图像描述在这里

英文:

I managed to correct the code to get the map I wanted.

import matplotlib.pyplot as plt
import cartopy
import cartopy.crs as ccrs
import numpy as np
import xarray as xr
import matplotlib.path as mpath
ds = xr.open_dataset(r'R:\Python\qnew_1000.nc')
ds2 = ds['qq'].mean(dim='time')
minn = ds2.min()
maxx = ds2.max()
noProj = ccrs.PlateCarree()
myProj = ccrs.LambertConformal(central_longitude=0, central_latitude=55)
myProj._threshold = myProj._threshold/20.
plt.figure(figsize=(8,8))
axs = plt.axes(projection=myProj)
[axs_hdl] = axs.plot([60, -60, -60, 60, 60], [20, 20, 85, 85, 20],
color='black', linewidth=0.5, marker='none',
transform=noProj)
tx_path = axs_hdl._get_transformed_path()
path_in_data_coords, _ = tx_path.get_transformed_path_and_affine()
polygon = mpath.Path(path_in_data_coords.vertices)
axs.set_boundary(polygon) #This masks-out unwanted part of the plot
axs.set_xmargin(0)
axs.set_ymargin(0)
axs.set_global()
axs.add_feature(cartopy.feature.OCEAN, linewidth=.3, color='lightblue')
axs.add_feature(cartopy.feature.LAND, zorder=1, edgecolor='black')
axs.add_feature(cartopy.feature.COASTLINE, linewidth=0.5)
axs.add_feature(cartopy.feature.BORDERS, linewidth=0.5)
axs.set_extent([-60, 60, 20, 85], crs=noProj)
axs.tick_params(axis='both', which='major', labelsize=10)
axs.set_title("")
gl=axs.gridlines(draw_labels=True, x_inline=False, y_inline=False, color='k', linestyle='dashed', linewidth=0.5)
gl.top_labels = False
pcm = axs.pcolormesh(ds2.longitude, ds2.latitude, ds2, transform=ccrs.PlateCarree(), 
vmin=minn, vmax=maxx, cmap='jet',
shading='nearest')
cbar = plt.colorbar(pcm, ax=axs, orientation='horizontal', pad=0.08, shrink=0.8)
cbar.set_label('(g kg$^{-1}$)')
plt.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.95, wspace=0.2, hspace=0.2)
plt.savefig("figure.jpg", dpi=300, bbox_inches='tight', pad_inches=0.1, format='jpg', facecolor="w", transparent=False)
plt.show()

enter image description here

huangapple
  • 本文由 发表于 2023年3月9日 22:05:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/75685694.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定