<p>感谢@ImportanceOfBeingErnest提供解决方案。我试图编辑他/她的解决方案来解决一些小问题,但最终他/她建议我发布自己的答案。在</p>
<p>这个解决方案和他/她的一样,但是当没有指定标记阵列时,它不会改变法向散射的行为。它的应用也更简单,它修复了图例失去标题的错误。在</p>
<p>下图由以下代码生成:</p>
<p><a href="https://i.stack.imgur.com/XoXm9.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/XoXm9.png" alt="enter image description here"/></a></p>
<pre><code>import seaborn as sns
import matplotlib.pyplot as plt
############## Begin hack ##############
from matplotlib.axes._axes import Axes
from matplotlib.markers import MarkerStyle
from seaborn import color_palette
from numpy import ndarray
def GetColor2Marker(markers):
palette = color_palette()
mkcolors = [(palette[i]) for i in range(len(markers))]
return dict(zip(mkcolors,markers))
def fixlegend(ax,markers,markersize=8,**kwargs):
# Fix Legend
legtitle = ax.get_legend().get_title().get_text()
_,l = ax.get_legend_handles_labels()
palette = color_palette()
mkcolors = [(palette[i]) for i in range(len(markers))]
newHandles = [plt.Line2D([0],[0], ls="none", marker=m, color=c, mec="none", markersize=markersize,**kwargs) \
for m,c in zip(markers, mkcolors)]
ax.legend(newHandles,l)
leg = ax.get_legend()
leg.set_title(legtitle)
old_scatter = Axes.scatter
def new_scatter(self, *args, **kwargs):
colors = kwargs.get("c", None)
co2mk = kwargs.pop("co2mk",None)
FinalCollection = old_scatter(self, *args, **kwargs)
if co2mk is not None and isinstance(colors, ndarray):
Color2Marker = GetColor2Marker(co2mk)
paths=[]
for col in colors:
mk=Color2Marker[tuple(col)]
marker_obj = MarkerStyle(mk)
paths.append(marker_obj.get_path().transformed(marker_obj.get_transform()))
FinalCollection.set_paths(paths)
return FinalCollection
Axes.scatter = new_scatter
############## End hack. ##############
# Example Test
sns.set(style="whitegrid")
tips = sns.load_dataset("tips")
# To test robustness
tips.loc[(tips['sex']=="Male") & (tips['day']=="Fri"),'sex']='Female'
tips.loc[(tips['sex']=="Female") & (tips['day']=="Sat"),'sex']='Male'
Markers = ["o","P"]
fig, axs = plt.subplots(1,2,figsize=(14,5))
axs[0] = sns.swarmplot(x="day", y="total_bill", hue="sex",data=tips,size=8,ax=axs[0])
axs[0].set_title("Original")
axs[1] = sns.swarmplot(x="day", y="total_bill", hue="sex",data=tips,size=8,ax=axs[1],co2mk=Markers)
axs[1].set_title("Hacked")
fixlegend(axs[1],Markers)
plt.show()
</code></pre>