Some of the data labels of the SHAP waterfall plot that I get are equal to zero. However, they are not and the plot itself rounds them. Therefore, I need to increase the decimal places of the labels. The following is the part of the code for this purpose:
plt.figure()
fig, ax = plt.subplots()
fig.tight_layout(pad=7.0)
shap.plots.waterfall(val[26], show=False)
for text in ax.texts:
text.set_color('k')
value = float(text.get_text())
text.set_text(f"{value:.{4}f}")
fig, ax = plt.gcf(), plt.gca()
ax.grid(axis='y', color='grey', linestyle=':', linewidth=1, alpha=0.5)
for tick in ax.get_xticklabels():
tick.set_fontname('Times New Roman')
tick.set_fontsize(14)
tick.set_color('k')
for tick in ax.get_yticklabels():
tick.set_fontname('Times New Roman')
tick.set_fontsize(14)
tick.set_color('k')
ax.spines["top"].set_visible(True)
ax.spines["top"].set_color('k')
ax.spines["left"].set_visible(True)
ax.spines["left"].set_color('k')
ax.spines["right"].set_visible(True)
ax.spines["right"].set_color('k')
plt.show()
So far, I have tried the code below but it returns a value error. This is because despite being numbers, the labels are strings, and it does not affect them.
for text in ax.texts:
value = float(text.get_text())
text.set_text(f"{value:.{4}f}")
I have also tried increasing the decimal places for the whole Python environment but it did not help due to the same reason as above. I used the method below:
from decimal import getcontext
getcontext().prec = 4
The plot that I get is as follows:
Some of the data labels of the SHAP waterfall plot that I get are equal to zero. However, they are not and the plot itself rounds them. Therefore, I need to increase the decimal places of the labels. The following is the part of the code for this purpose:
plt.figure()
fig, ax = plt.subplots()
fig.tight_layout(pad=7.0)
shap.plots.waterfall(val[26], show=False)
for text in ax.texts:
text.set_color('k')
value = float(text.get_text())
text.set_text(f"{value:.{4}f}")
fig, ax = plt.gcf(), plt.gca()
ax.grid(axis='y', color='grey', linestyle=':', linewidth=1, alpha=0.5)
for tick in ax.get_xticklabels():
tick.set_fontname('Times New Roman')
tick.set_fontsize(14)
tick.set_color('k')
for tick in ax.get_yticklabels():
tick.set_fontname('Times New Roman')
tick.set_fontsize(14)
tick.set_color('k')
ax.spines["top"].set_visible(True)
ax.spines["top"].set_color('k')
ax.spines["left"].set_visible(True)
ax.spines["left"].set_color('k')
ax.spines["right"].set_visible(True)
ax.spines["right"].set_color('k')
plt.show()
So far, I have tried the code below but it returns a value error. This is because despite being numbers, the labels are strings, and it does not affect them.
for text in ax.texts:
value = float(text.get_text())
text.set_text(f"{value:.{4}f}")
I have also tried increasing the decimal places for the whole Python environment but it did not help due to the same reason as above. I used the method below:
from decimal import getcontext
getcontext().prec = 4
The plot that I get is as follows:
Share Improve this question edited Jan 17 at 20:38 PW14 asked Jan 17 at 19:51 PW14PW14 374 bronze badges1 Answer
Reset to default 2That was subtle!
I checked your code on a dataset and I got this error:
ValueError: could not convert string to float: '−0.21'
It is a small detail but if you look closely you may notice that the minus sign almost touches 0 so I wondered if it was really a minus sign. If you take the unicode of the first character with ord() you get 8722, whereas it should be 45 for a normal minus sign.
So the solution is to check the strings if they have this code and if so replace it by the real minus sign to get the string of a negative number which can be converted by float():
for text in ax.texts:
text.set_color('k')
ctext = text.get_text()
if ord(ctext[0]) == 8722:
ctext = "-" + ctext[1:]
value = float(ctext)
text.set_text(f"{value:.{4}f}")