How to decode encoded labels in Decision tree classifier
First, setting feature_names will replace all the X[2] and such.  Using feature_names=data.columns is sensible, provided your feature names aren't too long for easy display.
Now, you'll still be comparing against the label encodings.  By saving the label encoder objects (your encoder dict), you can retrieve which levels correspond to the integer labels (with the classes_ attribute, or possibly the inverse_transform method).  If your features have many levels, then you probably don't want to display all the levels in each split, and just providing them off to the side somewhere might be best.  If your features have few levels, maybe hacking the resulting DOT code will work; see this related answer of mine, which concerns one-hot encoded variables.