-
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
When using log-scale on the x-axis catplot
gives wrong results
#2006
Comments
Setting a log scale on the x axis doesn't make sense.
Because you're setting the attributes directly at the matplotlib layer, there's nothing that can be done to prevent you from trying. But there should be no expectation that it will work. |
Thanks for the response @mwaskom! I am sorry to say that, but it is kind of hard to agree here. First, data visualization of that kind should be agnostic to what the user tries to visualize. Why is it not valid to investigate a logarithmic functional dependency of a categorical variable? Esp., since the function has a Despite from that, the mentioned note in the docs and the presumed fact that "log-scale does not make sense if x is categorical" will most probably not be apparent for the majority of seaborn users. Just like Hence, I see quite some risk that this can be a pitfall for many others. And without knowing how complex it would be to fix it, I would love to simply see it working as (wrongly) expected :) |
Anyway, just in case other stumble upon this issue: You can simply use the import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
xx, yy = np.meshgrid(np.arange(1., 4.),
np.round(np.logspace(0, 2, 10), 2))
df = pd.DataFrame(np.stack([xx.ravel(), yy.ravel()]).T,
columns=['variable', 'x'])
df['value'] = np.log10(df['variable'] * df['x'])
def logplot(x, y, **kwargs):
ax = plt.gca()
data = kwargs.pop("data")
data.plot(x, y, ax=ax, style='.-', ms=15, lw=2, grid=True, **kwargs)
ax.set_xscale("log")
g = sns.FacetGrid(df, hue='variable', aspect=1.5, height=5.)
g = g.map_dataframe(logplot, "x", "value")
g.add_legend() Result: |
Just another proposal @mwaskom: to be on the safe side it would be a good measure to protect the user from making this mistake. Since, for example, import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
xx, yy = np.meshgrid(np.arange(1., 4.),
np.round(np.logspace(0, 2, 10), 2))
df = pd.DataFrame(np.stack([xx.ravel(), yy.ravel()]).T,
columns=['variable', 'x'])
df['value'] = np.log10(df['variable'] * df['x'])
g = sns.catplot(x='x', y='value', hue='variable',
data=df, aspect=1.5, kind="point")
# Example how to patch the `set` method
def set_safe(self, **kwargs):
if 'xscale' in kwargs and kwargs['xscale'] == 'log':
raise ValueError('Setting log scale on a categorical axis is '
'not valid.')
return self.set(**kwargs)
set_safe(g, xscale="log") # <-- comment/uncomment this line to see the issue
plt.grid(which='both') Of course this should happen as a monkey-patch on the Note: a cleaner way would be to use a subclass of |
The x-axis seems broken when switching to log-scale after plotting with
catplot
viaset(xscale="log")
. Here is a minimum working example:With linear scale (
g.set(xscale="log")
commented out) this creates:With log-scale it gives:
Issues observed with log-scale:
Environment:
matplotlib
: 3.0.2seaborn
: 0.9.0matplotlib
backend:'module://ipykernel.pylab.backend_inline'
The text was updated successfully, but these errors were encountered: