Victor Valente
Victor Valente

Reputation: 801

Matplotlib/Seaborn: how to plot a rugplot on the top edge of x-axis?

Suppose I draw a plot using the code below. How to plot the rug part on the top edge of x-axis?

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

sns.distplot(np.random.normal(0, 0.1, 100), rug=True, hist=False)
plt.show()

enter image description here

Upvotes: 1

Views: 2349

Answers (2)

Sheldore
Sheldore

Reputation: 39052

Rugs are just thin lines at the data points. Yo can think of them as thin bars. That being said, you can have a following work around: Plot distplot without rugs and then create a twin x-axis and plot a bar chart with thin bars. Following is a working answer:

import numpy as np; np.random.seed(21)
import matplotlib.pyplot as plt
import seaborn as sns

fig, ax = plt.subplots()

data = np.random.normal(0, 0.1, 100)
sns.distplot(data, rug=False, hist=False, ax=ax)

ax1 = ax.twinx()
ax1.bar(data, height=ax.get_ylim()[1]/10, width=0.001)
ax1.set_ylim(ax.get_ylim())
ax1.invert_yaxis()
ax1.set_yticks([])
plt.show()

enter image description here

Upvotes: 1

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339210

The seaborn.rugplot creates a LineCollection with the length of the lines being defined in axes coordinates. Those are always the same, such that the plot does not change if you invert the axes.

You can create your own LineCollection from the data though. The advantage compared to using bars is that the linewidth is in points and therefore no lines will be lost independend of the data range.

import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt
import seaborn as sns

def upper_rugplot(data, height=.05, ax=None, **kwargs):
    from matplotlib.collections import LineCollection
    ax = ax or plt.gca()
    kwargs.setdefault("linewidth", 1)
    segs = np.stack((np.c_[data, data],
                     np.c_[np.ones_like(data), np.ones_like(data)-height]),
                    axis=-1)
    lc = LineCollection(segs, transform=ax.get_xaxis_transform(), **kwargs)
    ax.add_collection(lc)

fig, ax = plt.subplots()

data = np.random.normal(0, 0.1, 100)
sns.distplot(data, rug=False, hist=False, ax=ax)

upper_rugplot(data, ax=ax)

plt.show()

enter image description here

Upvotes: 2

Related Questions