Reputation: 1005
Here's one example of Basemap:
fig = plt.figure(figsize=(10,6))
ax = fig.add_subplot(121)
ax.set_title('Default')
# miller projection
map = Basemap(projection='mill',lon_0=180)
# plot coastlines, draw label meridians and parallels.
map.drawcoastlines()
map.drawparallels(np.arange(-90,90,30),labels=[1,0,0,0])
map.drawmeridians(np.arange(map.lonmin,map.lonmax+30,60),labels=[0,0,0,1])
ax = fig.add_subplot(122)
ax.set_title('Add offset')
# miller projection
map = Basemap(projection='mill',lon_0=180)
# plot coastlines, draw label meridians and parallels.
map.drawcoastlines()
map.drawparallels(np.arange(-90,90,30),labels=[1,0,0,0],xoffset=100,yoffset=100)
map.drawmeridians(np.arange(map.lonmin,map.lonmax+30,60),labels=[0,0,0,1],xoffset=100,yoffset=100)
I want to add more space between the xlabel/ylabel and axis.
But, the space is smaller when xoffset
and yoffset
are added.
Upvotes: 1
Views: 808
Reputation: 3266
I think you are not using the correct unit. @Thomas Kühn quoted the basemap doc:
xoffset: label offset from edge of map in x-direction (default is 0.01 times width of map in map projection coordinates).
yoffset: label offset from edge of map in y-direction (default is 0.01 times height of map in map projection coordinates).
Note that it is defaulted to 1% of the domain span measured in map projection coordinates.
If you check the span in y-axis of the mill projection you used, the length has 8 digits, so no wonder yoffset=100
gives no visual offset.
So an easier way is to modify the offset using the actual domain span, like:
map.drawmeridians(np.arange(map.lonmin,map.lonmax+30,60),labels=[0,0,0,1],
yoffset=0.01*abs(map.ymax-map.ymin))
This gives the same offset as default, i.e. 1% of the domain span (See figure (b) below). Changing 0.01
to 0.03
will be 3x of that (figure (c)).
If you instead use cyl
projection which uses degree of latitude/longitude as units, the offsets are also measured in degrees, then yoffset=100
will be an insane offset. Figure (f) uses a yoffset=30
, note that is the same distance as the distance from 60S to 90S.
The script to generate the figure:
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import numpy as np
fig = plt.figure(figsize=(12,6))
def drawMap(proj):
map = Basemap(projection=proj,lon_0=180)
map.drawcoastlines()
return map
# miller projection
ax = fig.add_subplot(231)
ax.set_title('(a) Mill, Default')
map=drawMap('mill')
map.drawparallels(np.arange(-90,90,30),labels=[1,0,0,0])
map.drawmeridians(np.arange(map.lonmin,map.lonmax+30,60),labels=[0,0,0,1])
ax = fig.add_subplot(232)
ax.set_title('(b) Mill, add same offset as default')
map=drawMap('mill')
map.drawparallels(np.arange(-90,90,30),labels=[1,0,0,0],
xoffset=0.01*abs(map.xmax-map.xmin))
map.drawmeridians(np.arange(map.lonmin,map.lonmax+30,60),labels=[0,0,0,1],
yoffset=0.01*abs(map.ymax-map.ymin))
ax = fig.add_subplot(233)
ax.set_title('(c) Mill, add 3x offset as default')
map=drawMap('mill')
map.drawparallels(np.arange(-90,90,30),labels=[1,0,0,0],
xoffset=0.03*abs(map.xmax-map.xmin))
map.drawmeridians(np.arange(map.lonmin,map.lonmax+30,60),labels=[0,0,0,1],
yoffset=0.03*abs(map.ymax-map.ymin))
ax = fig.add_subplot(234)
ax.set_title('(d) Cyl, Default')
map=drawMap('cyl')
map.drawparallels(np.arange(-90,90,30),labels=[1,0,0,0])
map.drawmeridians(np.arange(map.lonmin,map.lonmax+30,60),labels=[0,0,0,1])
ax = fig.add_subplot(235)
ax.set_title('(e) Cyl, add same offset as default')
map=drawMap('cyl')
map.drawparallels(np.arange(-90,90,30),labels=[1,0,0,0],
xoffset=0.01*abs(map.xmax-map.xmin))
map.drawmeridians(np.arange(map.lonmin,map.lonmax+30,60),labels=[0,0,0,1],
yoffset=0.01*abs(map.ymax-map.ymin))
ax = fig.add_subplot(236)
ax.set_title('(f) Cyl, add 30 degree offset')
map=drawMap('cyl')
map.drawparallels(np.arange(-90,90,30),labels=[1,0,0,0],
xoffset=0.03*abs(map.xmax-map.xmin))
map.drawmeridians(np.arange(map.lonmin,map.lonmax+30,60),labels=[0,0,0,1],
yoffset=30)
fig.subplots_adjust(hspace=0.01)
fig.show()
Upvotes: 0
Reputation: 9810
basemap
is not being actively developed anymore, but maintenance still continues for some time. This means that things that break because of changes in other packages will still be fixed, but no new features will be added. Anyway, the fixing part may take some time and I'm guessing that the xoffset
feature for the parallels and meridians is suffering from that. However, looking at the basemap
documentation, the functionality of xoffset
and yoffset
are described as
xoffset: label offset from edge of map in x-direction (default is 0.01 times width of map in map projection coordinates).
yoffset: label offset from edge of map in y-direction (default is 0.01 times height of map in map projection coordinates).
This is easy enough to emulate by manipulating the Text
objects that drawparallels()
and drawmeridians()
produce. The results of these functions are stored in a dict
that contains a tuple of lists for each plotted parallel/meridian, the second of which contains the text labels. A Text
object has a get_position()
and a set_position()
method, which, in combination with the axes limits and the definition above, can be used to compute the offset:
from matplotlib import pyplot as plt
from mpl_toolkits.basemap import Basemap
import numpy as np
fig = plt.figure(figsize=(10,6))
ax = fig.add_subplot(121)
ax.set_title('Default')
# miller projection
map = Basemap(projection='mill',lon_0=180)
# plot coastlines, draw label meridians and parallels.
map.drawcoastlines()
map.drawparallels(np.arange(-90,90,30),labels=[1,0,0,0])
map.drawmeridians(np.arange(map.lonmin,map.lonmax+30,60),labels=[0,0,0,1])
ax = fig.add_subplot(122)
ax.set_title('Add offset')
# miller projection
map = Basemap(projection='mill',lon_0=180)
# plot coastlines, draw label meridians and parallels.
map.drawcoastlines()
##getting axes dimensions
x0,x1 = ax.get_xlim()
w = x1-x0
y0,y1 = ax.get_ylim()
h = y1-y0
xoffset = 0.05
yoffset = 0.05
result = map.drawparallels(np.arange(-90,90,30),labels=[1,0,0,0])
##
for key, (lines,texts) in result.items():
for text in texts:
x,y = text.get_position()
text.set_position((x0-xoffset*w,y))
result = map.drawmeridians(np.arange(map.lonmin,map.lonmax+30,60),labels=[0,0,0,1])
for key, (lines,texts) in result.items():
for text in texts:
x,y = text.get_position()
text.set_position((x,y0-yoffset*h))
plt.show()
The resulting plot looks like this:
Upvotes: 1