Rotating Basemap Meridian labels on x-axis - python

Is it possible to rotate the meridian labels so that they are no longer overlapping? See the image for an example below. I don't want to reduce the number of meridian lines.
I've tried:
ax = plt.gca()
ax.set_xticklabels( meridians, rotation=45 )
This doesn't do anything in Basemap though.

The meridian labels aren't xaxis labels. You can still manipulate their text objects:
from mpl_toolkits.basemap import Basemap, cm
import numpy as np
import matplotlib.pyplot as plt
# create figure and axes instances
fig = plt.figure(figsize=(8,8))
ax = fig.add_axes([0.1,0.1,0.8,0.8])
# create polar stereographic Basemap instance.
m = Basemap(projection='stere',lon_0=0,lat_0=30.,lat_ts=45.,\
width=10000000, height=4000000,
rsphere=6371200.,resolution='l',area_thresh=10000)
m.drawcoastlines()
m.drawstates()
m.drawcountries()
# draw parallels.
parallels = np.arange(0.,90,5.)
m.drawparallels(parallels,labels=[1,0,0,0],fontsize=10)
# draw meridians
merid_values = np.arange(0.,360.,10.)
meridians = m.drawmeridians(merid_values,labels=[0,0,0,1],fontsize=10)
for m in meridians:
try:
meridians[m][1][0].set_rotation(45)
except:
pass
plt.show()

Just give an angle as the "rotation" argument of the mapproj.drawmeridians().
import mpl_toolkits.basemap as bm
mapproj = bm.Basemap(ax=ax1,projection='cyl',llcrnrlat=lat_mn, \
llcrnrlon= lon_mn,urcrnrlat= lat_mx, urcrnrlon=lon_mx)
mapproj.drawmeridians(lonlines, labels=[0,0,1,0],rotation=45)
That's it!
Cheers!

Related

How to keep nested axes position while using subplots_adjust

I use the following code to add a colorbar at the top left corner of each subplot.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import gridspec
# Create figure
fig = plt.figure(figsize=(5, 2))
# Specify geometry of the grid for subplots
gs0 = gridspec.GridSpec(1, 3, wspace=0.7)
# Data
a = np.arange(3*5).reshape(3,5)
for ax_i in range(3):
# Create axes
ax = plt.subplot(gs0[ax_i])
# Plot data
plot_pcolor = plt.pcolormesh(a)
# ******** Plot a nested colorbar inside the plot ********
# Define position of the desired colorbar in axes coordinate
# [(lower left x, lower left y), (upper right x, upper right y)]
ax_coord = [(0.05, 0.5), (0.2, 0.95)]
# Transform the two points from axes coordinates to display coordinates
tr1 = ax.transAxes.transform(ax_coord)
# Create an inverse transversion from display to figure coordinates
inv = fig.transFigure.inverted()
tr2 = inv.transform(tr1)
# Position in figure coordinates [left, bottom, width, height]
datco = [tr2[0,0], tr2[0,1], tr2[1,0]-tr2[0,0], tr2[1,1]-tr2[0,1]]
# Create colorbar axes
cbar_ax = fig.add_axes(datco)
# Plot colorbar
cbar = plt.colorbar(plot_pcolor, cax=cbar_ax)
# ********************************************************
if False:
plt.subplots_adjust(left=0.15, bottom=0.2, right=0.95, top=0.8)
plt.savefig('test.png', dpi=500)
which gives the following plot:
However, if I use the subplots_adjust() function (by replacing False to True in the code above), the colorbars do not move properly:
Do you know how I can handle it?
Using the inset_axes() function from the mpl_toolkits module solves the problem. It is also possible to simply use ax.inset_axes().
Here is the new code:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import gridspec
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
# Create figure
fig = plt.figure(figsize=(5, 2))
# Specify geometry of the grid for subplots
gs0 = gridspec.GridSpec(1, 3, wspace=0.7)
# Data
a = np.arange(3*5).reshape(3,5)
for ax_i in range(3):
# Create axes
ax = plt.subplot(gs0[ax_i])
# Plot data
plot_pcolor = plt.pcolormesh(a)
axins = inset_axes(ax, width="5%", height="50%", loc='upper left')
# Plot colorbar
cbar = plt.colorbar(plot_pcolor, cax=axins)
# ********************************************************
if True:
plt.subplots_adjust(left=0.15, bottom=0.2, right=0.95, top=0.8)
plt.savefig('test.png', dpi=500)
Here is the result:

Matplotlib: Making axes fit shape limits

I'm trying to draw a rectangle in matplotlib using the following code:
import matplotlib.pyplot as plt
import matplotlib.patches as patches
fig, ax = plt.subplots()
width = 20
height = 10
rect = patches.Rectangle((0,0),width, height, linewidth=4,edgecolor='r',facecolor='none')
ax.add_patch(rect)
plt.show()
Which results in:
The axes do not fit the rectangle limits in this case. I could solve it with:
import matplotlib.pyplot as plt
import matplotlib.patches as patches
fig, ax = plt.subplots()
width = 20
height = 10
ax.set_xlim(0,width)
ax.set_ylim(0,height)
rect = patches.Rectangle((0,0),width, height, linewidth=4,edgecolor='r',facecolor='none')
ax.add_patch(rect)
plt.show()
This gives me the following picture which solves the problem in this case:
However, as I am trying to plot many rectangles and other shapes in the same figure, I need a way that matplotlib smartly determines the proper axes limits itself, like the way it does when plotting normal diagrams.
You are looking for .autoscale(). You may use .margins(0) to remove any extra space that is added by default.
I.e.
import matplotlib.pyplot as plt
import matplotlib.patches as patches
fig, ax = plt.subplots()
width = 20
height = 10
rect = patches.Rectangle((0,0),width, height, linewidth=4,edgecolor='r',facecolor='none')
ax.add_patch(rect)
ax.margins(0)
ax.autoscale()
plt.show()

How do I draw a polygon with dark borders but transparent facecolors?

In matplotlib I have:
cmap = plt.cm.RdYlBu_r
colors = cmap(np.linspace(0,1, len(patches)))
collection = PatchCollection(patches, alpha=.3,
facecolor=colors, linestyle='solid')
and it gives me what I want except that the border inherits the "alpha" attribute. How do I draw a polygon with dark borders but transparent facecolors?
as a by-pass solution you could keep the points composing your polygon and plot the line joining the points as in the code below:
import matplotlib
import numpy,matplotlib.pyplot as plt
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection
fig = plt.figure()
axe = fig.add_subplot(111)
polyval = numpy.random.rand(4,2) # Create the sequence of 4 2D points
patches = [Polygon(polyval,True)]
p = PatchCollection(patches,cmap=matplotlib.cm.jet,alpha=0.3)
p.set_array(100.*numpy.random.rand(1)) # Set a random color on jet map
axe.add_collection(p)
fig.colorbar(p)
fig.show()
for patch in patches:
axe.add_patch(Polygon(patch.get_xy(),closed=True,ec='k',lw=3,fill=False)) #draw the contours
fig.canvas.draw()

Plotting text on basemap

Suppose I want to plot 'text' on a basemap over Spain, this would work.
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
m = Basemap(resolution='l')
fig = plt.figure(figsize=(12,10))
m.drawcoastlines(linewidth=0.5)
plt.annotate('Text',xy=(0,40),ha="center")
plt.show()
But it doesn't work on Merc view, no matter what x/y value I specify. E.g:
m = Basemap(projection='merc',resolution='c',llcrnrlat=36,llcrnrlon=-20,urcrnrlat=61,urcrnrlon=33)
fig = plt.figure(figsize=(12,10))
m.drawcoastlines(linewidth=0.5)
plt.annotate('Text',xy=(0,40),ha="center")
plt.show()
Will only show the text in the very bottom left. How to plot text in this view?

Place pie charts on a map using Basemap

I would like to plot pie charts on a map using Basemap and Matplotlib.
Do you know a way to do this?
You can add an axes to a basemap with inset_axes . I've modified the first example here to include a pie chart.
from mpl_toolkits.basemap import Basemap
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
import matplotlib.pyplot as plt
# setup Lambert Conformal basemap.
fig = plt.figure()
ax = fig.add_subplot(111)
m = Basemap(width=12000000,height=9000000,projection='lcc',
resolution='c',lat_1=45.,lat_2=55,lat_0=50,lon_0=-107.,ax=ax)
# draw coastlines.
m.drawcoastlines()
# draw a boundary around the map, fill the background.
# this background will end up being the ocean color, since
# the continents will be drawn on top.
m.drawmapboundary(fill_color='aqua')
# fill continents, set lake color same as ocean color.
m.fillcontinents(color='coral',lake_color='aqua')
axin = inset_axes(m.ax,width="30%",height="30%", loc=3)
axin.pie([100,200,3000])
plt.show()

Categories