basemap: How to remove actual lat/lon lines while keeping the ticks on the axis
This can be easily achieved by setting the linewidth
parameter to zero
m.drawparallels(np.arange(int(40.125),int(44.625),1),labels=[1,0,0,0], linewidth=0.0)
m.drawmeridians(np.arange(int(-71.875),int(-66.375),1),labels=[0,0,0,1], linewidth=0.0)
I found the basemap ticks setting quite confusing.
The figure below shows 8 different setups. Some notations:
ST=T
:suppress_ticks=True
.ST=F
:suppress_ticks=False
.DP-DR
:drawparallels()
anddrawmeridians()
.DP-DR(LW=0)
:drawparallels(...,linewidth=0)
anddrawmeridians(...,linewidth=0)
.mill
: miller map projection.
Interpret the results in the top panel:
- (a): This is the same as the OP's figure, i.e. using
suppress_ticks=True
(the default) anddrawparallels()
anddrawmeridians()
. - (b): Solution suggested by @Greg, setting
linewidth=0
todrawparallels()
anddrawmeridians()
removes the grid lines, but not adding the ticks. Note the title of the question is "How to remove actual lat/lon lines while keeping the ticks on the axis". - (c): Solution suggested by @Janusz. Note that setting
suppress_ticks=False
alone does not remove the grid lines, instead it adds an extra set of ticks. That's whysuppress_ticks
is default toTrue
. - (d): Combine (b) and (c).
linewidth=0
is what actually removes the grid lines. Againsuppress_ticks=False
introduces extra ticks, and they overlap with ticks added bydrawparallels()
anddrawmeridians()
.
2nd panel:
- (e): What if we don't use
drawparallels()
anddrawmeridians()
and let it automatically add ticks? The 1st drawback is that you don't get to control which ticks to add. Another one is the tick labels are formatted without theW/E
,N/S
symbols (if you addlabelstyle='+/-'
todrawparallels()
ordrawmeridians()
, the labels will use+ 41^{\circ}
format). And there is another big drawback, as shown in (f). - (f): This is using
mill
map projection instead ofcyl
. Notice the automatic labeling uses meter as unit rather than degree of latitude/longitude. Not good (at least in this case). - (g): This is trying to add the tickmarks by manually setting ticks, by
ax.set_xticks(lon_ticks)
andax.set_yticks(lat_ticks)
. The ticks are added, but labels overlap. - (h): This is my proposed solution again using
mill
projection:
m = Basemap(projection='mill',llcrnrlat=40.125,urcrnrlat=44.625,\
llcrnrlon=-71.875,urcrnrlon=-66.375,resolution='l',
ax=ax8, fix_aspect=False,
suppress_ticks=True)
m.drawcoastlines()
lat_ticks=np.arange(np.ceil(40.125),int(44.625),1)
lon_ticks=np.arange(np.ceil(-71.875),int(-66.375),1)
# convert from degree to map projection
lon_ticks_proj, _=m(lon_ticks, np.zeros(len(lon_ticks)))
_, lat_ticks_proj=m(np.zeros(len(lat_ticks)), lat_ticks)
# manually add ticks
ax8.set_xticks(lon_ticks_proj)
ax8.set_yticks(lat_ticks_proj)
ax8.tick_params(axis='both',which='major')
# add ticks to the opposite side as well
ax8.xaxis.set_ticks_position('both')
ax8.yaxis.set_ticks_position('both')
# remove the tick labels
ax8.xaxis.set_ticklabels([])
ax8.yaxis.set_ticklabels([])
m.drawparallels(lat_ticks,labels=[1,0,0,0],linewidth=0,
xoffset=0.03*abs(m.xmax-m.xmin)) # need to enlarge the offset a bit
m.drawmeridians(lon_ticks,labels=[0,0,0,1],linewidth=0,
yoffset=0.03*abs(m.ymax-m.ymin)) # need to enlarge the offset a bit
Finally, the script to create the figure:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
def getBM(ax, suppress_ticks, projection='cyl'):
m = Basemap(projection=projection,llcrnrlat=40.125,urcrnrlat=44.625,\
llcrnrlon=-71.875,urcrnrlon=-66.375,resolution='l',
ax=ax, fix_aspect=False,
suppress_ticks=suppress_ticks)
m.drawcoastlines()
return m
lat_ticks=np.arange(np.ceil(40.125),int(44.625),1)
lon_ticks=np.arange(np.ceil(-71.875),int(-66.375),1)
figure=plt.figure(figsize=(14,7),dpi=100)
nrows=2; ncols=4
#------------------------s1------------------------
ax1=figure.add_subplot(nrows,ncols,1)
m = getBM(ax1, True)
m.drawparallels(lat_ticks,labels=[1,0,0,0])
m.drawmeridians(lon_ticks,labels=[0,0,0,1])
ax1.set_title('(a) ST=T, DP-DR')
#------------------------s2------------------------
ax2=figure.add_subplot(nrows,ncols,2)
m = getBM(ax2, True)
m.drawparallels(lat_ticks,labels=[1,0,0,0],linewidth=0)
m.drawmeridians(lon_ticks,labels=[0,0,0,1],linewidth=0)
ax2.set_title('(b) ST=T, DP-DR(LW=0)')
#------------------------s3------------------------
ax3=figure.add_subplot(nrows,ncols,3)
m = getBM(ax3, False)
m.drawparallels(lat_ticks,labels=[1,0,0,0])
m.drawmeridians(lon_ticks,labels=[0,0,0,1])
ax3.set_title('(c) ST=F, DP-DR')
#------------------------s4------------------------
ax4=figure.add_subplot(nrows,ncols,4)
m = getBM(ax4, False)
m.drawparallels(lat_ticks,labels=[1,0,0,0],linewidth=0)
m.drawmeridians(lon_ticks,labels=[0,0,0,1],linewidth=0)
ax4.set_title('(d) ST=F, DP-DR(LW=0)')
#------------------------s5------------------------
ax5=figure.add_subplot(nrows,ncols,5)
m = getBM(ax5, False)
ax5.set_title('(e) ST=F')
#------------------------s6------------------------
ax6=figure.add_subplot(nrows,ncols,6)
m = getBM(ax6, False, projection='mill')
ax6.set_title('(f) ST=F, mill')
#------------------------s7------------------------
ax7=figure.add_subplot(nrows,ncols,7)
m = getBM(ax7, True)
ax7.set_xticks(lon_ticks)
ax7.set_yticks(lat_ticks)
m.drawparallels(lat_ticks,labels=[1,0,0,0],linewidth=0)
m.drawmeridians(lon_ticks,labels=[0,0,0,1],linewidth=0)
ax7.set_title('(g) ST=T, DP-DR(LW=0), manual tick')
#------------------------s8------------------------
ax8=figure.add_subplot(nrows,ncols,8)
m = getBM(ax8, True, projection='mill')
# convert from degree to map projection
lon_ticks_proj, _=m(lon_ticks, np.zeros(len(lon_ticks)))
_, lat_ticks_proj=m(np.zeros(len(lat_ticks)), lat_ticks)
# manually add ticks
ax8.set_xticks(lon_ticks_proj)
ax8.set_yticks(lat_ticks_proj)
ax8.tick_params(axis='both',which='major')
# add ticks to the opposite side as well
ax8.xaxis.set_ticks_position('both')
ax8.yaxis.set_ticks_position('both')
# remove the tick labels
ax8.xaxis.set_ticklabels([])
ax8.yaxis.set_ticklabels([])
m.drawparallels(lat_ticks,labels=[1,0,0,0],linewidth=0,
xoffset=0.03*abs(m.xmax-m.xmin)) # need to enlarge the offset a bit
m.drawmeridians(lon_ticks,labels=[0,0,0,1],linewidth=0,
yoffset=0.03*abs(m.ymax-m.ymin)) # need to enlarge the offset a bit
ax8.set_title('(g) ST=T, DP-DR(LW=0), manual tick*')
figure.tight_layout()
figure.show()
UPDATE: I'm having some issues with saved PDF files when using drawparallels(..., linewidth=0)
and drawmeridians(..., linewidth=0)
. More details are given at https://github.com/matplotlib/basemap/issues/493.
If you have the similar issue, consider using drawparallels(..., zorder=-2)
instead.
In basemap
you can set suppress_ticks=False
and you get the ticks without the lines.