How to put the variable names of pandas data frame on Diagonal of Seaborn PairGrid?
With minimal changes, I got this to work (python3.7.3, SeaBorn 0.9.0): 

import matplotlib.pyplot as plt
import seaborn as sns
iris = sns.load_dataset('iris')

# Add this before your call to map_diag
next_iris_label = iter(iris).__next__

def diagfunc(x, **kws):
  ax = plt.gca()
  #  replace x.name with `next_iris_label` call
  ax.annotate(next_iris_label(), xy=(0.05, 0.9), xycoords=ax.transAxes)

sns.PairGrid(iris).map_diag(diagfunc)


Output:


I dug into it and understood that the reason this fails is because once the IRIS dataset has been passed to SeaBorn.PairGrid, the original Names of observation columns are not retained. map_diag ends up calling diagfunc with diagonal components of the PairGrid, which do not have name property, let alone name anywhere else in the arguments passed.
Here is what is passed to the first time diagfunc is called:

{
    #  this is what you passed as positional parameter
    #  As you'll notice `x` is just an array, and 
    #   does not have any additional properties like a label
    'x': array([5.1, 4.9, , ... 5.9]), 
    #  these get passed in as **kws
    'label': '_nolegend_', 
    'color': (0.12156862745098039, 0.4666666666666667, 0.7058823529411765)
}


Now, if we could somehow iterate over all labels in IRIS dataset, we could put each one against the diagnoals of the PairGrid. Since diagfunc is called each time and has a new scope, I found that having an iterator that returned a new label each time it was called solves that.

next_iris_label defined as 

next_iris_label = iter(iris).__next__


solves that problem. This only has one constraint that I dont like, you will need to reset this by creating a new instance of the iterator by the binding statement next_iris_label = iter(iris).__next__ when you want to do such labelling again(otherwise it would throw a StopIteration error.)