-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FIX #3537 Disabling the legend based on the x-axis and hue values #3540
Conversation
Thanks for taking a crack at this, but it's not a sufficient change. First, that simple comparison will raise if any of the variables are specified using vector data (i.e. pandas series or numpy arrays, where the seaborn/seaborn/categorical.py Line 411 in 863539d
|
Thank you for responding. I have a brief inquiry. The problem of the legend not showing up occurs when the setting is "legend = auto." Yet, when it's set to "legend = full" or "legend = brief," it appears correctly, when hue and x values are same. Should the legend only be displayed when it's set to "True", or also when it's "full" or "brief"? |
|
Thanks, Based on your comment I have modified the code, legend title is disabled based on x and y values and hue datatype. |
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## master #3540 +/- ##
=======================================
Coverage 98.34% 98.34%
=======================================
Files 75 75
Lines 24605 24613 +8
=======================================
+ Hits 24197 24205 +8
Misses 408 408
|
seaborn/categorical.py
Outdated
# Obtaining the column names for hue, x, and y. | ||
hue_value = p.variables.get("hue") | ||
x_value = p.variables.get("x") | ||
y_value = p.variables.get("y") | ||
# Obtaining the datatype of hue | ||
hue_type = p.var_types.get("hue") | ||
if legend == 'auto' and hue_value in {x_value, y_value} \ | ||
and hue_type != 'numeric': | ||
# Setting the title of hue to None if hue matches "x" or | ||
# "y", or if the data type of "hue" is numeric. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you don't need all of this complexity; as in _configure_legend
you can take advantage of the _redundant_hue
property to cover the edge case.
Additionally, the conditional should guard the entire add_legend
call, not just what the title gets set to. The plot should not have a legend when legend="auto"
and the hue variable is redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initially, I started with what you suggested and found that in the current implementation when the x and hue columns are the same _redundant_hue
is set as True and show_legend
as False, which causes the legend data not to display, but the legend column is still displayed. so I went with modifying the title
Also if I comment the if show_legend
code in function _configure_legend
, even then legend title(that is day in this example) will be displayed. what I understood is in this function legend data is decided but not title
def _configure_legend(self, ax, func, common_kws=None, semantic_kws=None):
if self.legend == "auto":
show_legend = not self._redundant_hue and self.input_format != "wide"
else:
show_legend = bool(self.legend)
if show_legend:
self.add_legend_data(ax, func, common_kws, semantic_kws=semantic_kws)
handles, _ = ax.get_legend_handles_labels()
if handles:
ax.legend(title=self.legend_title)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not suggesting you modify _configure_legend
, I am suggesting you base the changes to the body of catplot
off of it. I think you just need the following patch
diff --git a/seaborn/categorical.py b/seaborn/categorical.py
index bb40d5d3..be68617a 100644
--- a/seaborn/categorical.py
+++ b/seaborn/categorical.py
@@ -3095,7 +3095,12 @@ def catplot(
g._update_legend_data(ax)
ax.legend_ = None
- if legend and "hue" in p.variables and p.input_format == "long":
+ if legend == "auto":
+ show_legend = not p._redundant_hue and p.input_format != "wide"
+ else:
+ show_legend = bool(legend)
+
+ if show_legend:
g.add_legend(title=p.variables.get("hue"), label_order=hue_order)
if data is not None:
There is a bit of copy-paste from _configure_legend
that could perhaps get abstracted away, but it's not a big deal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I overlooked that the class p contains the variable _redundant_hue. I've made the appropriate changes. Thanks
Can you please add a test? Essentially you want to assert that the |
Sure, I will add |
Thanks @abdulwaheedsoudagar |
) * FIX #3537 Disabling the legend based on the x-axis and hue values * FIX #3537 Disabling the legend based on the x-axis and hue values * FIX: catplot with redundant hue assignment creates empty legend with title #3537 * FIX: catplot with redundant hue assignment creates empty legend with title #3537 * FIX: catplot with redundant hue assignment creates empty legend with title #3537 * FIX: catplot with redundant hue assignment creates empty legend with title #3537 * FIX: catplot with redundant hue assignment creates empty legend with title #3537
Disable legend in case of redundancy
sns.catplot(tips, x="day", y="total_bill", hue="day", col="sex", row="smoker", kind="box", height=3)