Reputation: 548
%matplotlib inline
import seaborn as sns
titanic = sns.load_dataset('titanic')
ax1 = sns.distplot(titanic['fare'], kde=False, bins=15,)
# ax1.set_yscale('log')
for p in ax1.patches:
ax1.annotate(
s=f"{p.get_height():1.0f}",
xy=(p.get_x() + p.get_width() / 2., p.get_height()),
xycoords='data',
ha='center',
va='center',
fontsize=11,
color='black',
xytext=(0,7),
textcoords='offset points',
)
The above code plots the histogram for the Fare
of the titanic dataset, where each bar is annotated with its value using ax1.annotate
.
The trouble comes when I want to set the y scale to logc -- Uncomment the set_yscale
line and run it; it throws an error saying:
ValueError: Image size of 378x84035 pixels is too large. It must be less than 2^16 in each direction.
Perhaps the xycoords parameter should be changed, but I'm not quite sure what to change it too.
I'm on Python 3.7.2, seaborn is version 0.9.0. Matplotlib version 3.0.2, and I'm using the Inline backend.
Upvotes: 6
Views: 3399
Reputation: 339590
Some annotations are placed at y=0
. This will cause the position to be undefined on a logarithmic scale.
In a jupyter notebook with the inline backend the default option for showing figures is to run them through the bbox_inches="tight"
option of savefig
. This "tight" algrorithm is then unable to locate the labels and will extent the figure size to include them anyways.
The solution I would propose here is to set the clip_on
option of the annotations to True
. This will prevent annotations which are outside the axes to be visible. It thereby solves the problem of zero-placed annotations on the log scale.
import matplotlib.pyplot as plt
import seaborn as sns
titanic = sns.load_dataset('titanic')
ax1 = sns.distplot(titanic['fare'], kde=False, bins=15,)
ax1.set_yscale('log')
for p in ax1.patches:
ax1.annotate(
s=f"{p.get_height():1.0f}",
xy=(p.get_x() + p.get_width() / 2., p.get_height()),
xycoords='data',
ha='center',
va='center',
fontsize=11,
color='black',
xytext=(0,7),
textcoords='offset points',
clip_on=True, # <--- important
)
plt.savefig("outfig.png", bbox_inches="tight")
plt.show()
Upvotes: 6