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)

enter image description here


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() and drawmeridians().
  • DP-DR(LW=0): drawparallels(...,linewidth=0) and drawmeridians(...,linewidth=0).
  • mill: miller map projection.

enter image description here

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) and drawparallels() and drawmeridians().
  • (b): Solution suggested by @Greg, setting linewidth=0 to drawparallels() and drawmeridians() 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 why suppress_ticks is default to True.
  • (d): Combine (b) and (c). linewidth=0 is what actually removes the grid lines. Again suppress_ticks=False introduces extra ticks, and they overlap with ticks added by drawparallels() and drawmeridians().

2nd panel:

  • (e): What if we don't use drawparallels() and drawmeridians() 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 the W/E, N/S symbols (if you add labelstyle='+/-' to drawparallels() or drawmeridians(), 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 of cyl. 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) and ax.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.