matplotlib / matplotlib/basemap

zorder of drawmapboundary() gets on top of imshow()

Open
#474 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
817
Forks
395
PR merge metrics
No merged PRs in 30d

Description

Hi all,

I got this weird issue that changing the order of drawmapboundary() wrt drawparallels() and drawmeridians() gives different results. Specifically, calling drawmapboundary(fill_color='0.8') first leads to an overlay of grey over the imshow() (see left panel in figure). While putting drawmapboundary() after drawparallels() and drawmeridians() gives correct results (right panel in figure).

basemap

The script to create that plot:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap

def plotBmap(data, x, y, ax, order):

    bmap=Basemap(projection='cyl',\
            llcrnrlat=y[0],llcrnrlon=x[0],\
            urcrnrlat=y[-1],urcrnrlon=x[-1],\
            ax=ax)

    bmap.imshow(data, interpolation='nearest')

    # plot axes labels
    lat_labels=np.linspace(-90, 90, 5)
    lon_labels=np.linspace(0, 360, 6)
    ax.set_yticks(lat_labels)
    ax.set_xticks(lon_labels)
    ax.tick_params(axis='both',which='major',labelsize=10)
    ax.xaxis.set_ticklabels([])
    ax.yaxis.set_ticklabels([])

    # draw continents
    bmap.drawcoastlines(linewidth=1.5,linestyle='solid',color='k',\
        antialiased=True)
    bmap.drawcountries(linewidth=0.5,linestyle='solid',color='k',\
            antialiased=True)

    if order=='before':
        bmap.drawmapboundary(color='k',linewidth=1.0,fill_color='0.8')
        bmap.drawparallels(lat_labels,labels=[1,1,0,0],linewidth=0,\
                labelstyle='+/-',fontsize=10)
        bmap.drawmeridians(lon_labels,labels=[0,0,0,1],linewidth=0,\
                labelstyle='+/-',fontsize=10)
    elif order=='after':
        bmap.drawparallels(lat_labels,labels=[1,1,0,0],linewidth=0,\
                labelstyle='+/-',fontsize=10)
        bmap.drawmeridians(lon_labels,labels=[0,0,0,1],linewidth=0,\
                labelstyle='+/-',fontsize=10)
        bmap.drawmapboundary(color='k',linewidth=1.0,fill_color='0.8')

    return bmap

if __name__=='__main__':

    x=np.arange(0, 361, 1)     # lon
    y=np.arange(-90, 91, 1)    # lat
    X,Y=np.meshgrid(x,y)
    z=np.sin(X/90.)+np.cos(Y/90.)

    # create an area of missings
    z[10:50, 20:80]=np.nan

    fig, (ax1, ax2)=plt.subplots(1, 2, figsize=(12,6))

    bmap1=plotBmap(z, x, y, ax1, 'before')
    ax1.set_title('before')

    bmap2=plotBmap(z, x, y, ax2, 'after')
    ax2.set_title('after')

    fig.show()

I guess it's the zorder that is wrong. specifying zorder=0 in drawmapboundary() doesn't work, by zordre=-1 does.

The versions of relevant packages:

  • basemap = 1.2.0
  • matplotlib = 2.2.3

One of the combinations that doesn't have this issue:

  • basemap = 1.0.7
  • matplotlib = 2.2.3

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Use the provided plotBmap reproducer with Basemap 1.2.0 and Matplotlib 2.2.3, then compare its behavior with Basemap 1.0.7. Start by tracing drawmapboundary(), drawparallels(), and drawmeridians() as they create artists and z-orders. Done means drawmapboundary(fill_color='0.8') does not cover imshow() regardless of call order.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
data-visualization
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.