0

I would like to add a y-axis showing the count value for each category within my Joyplot, along the lines of what's possible with ggplot (e.g. Adding a secondary axis to ggplot2 ggridges (joyplot) to show counts in each bin):

desired output with count on y-axis

Example code:

import joypy
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import cm

iris = pd.read_csv("data/iris.csv")
fig, axes = joypy.joyplot(iris)

Current output:

joyplot example

Hoppity81
  • 61
  • 8
  • When drawing kde curves there are no bins, and therefore there's nothing that can be counted. Possibly you could mark the density, although it's a quite unintuitive measure. Note that in this drawing the axes would partly overlap. – JohanC Nov 23 '21 at 17:43
  • @JohanC thanks for your answer, that makes sense. If I was to instead plot it as a histogram, would it be possible to add a y-axis, e.g. fig, axes = joypy.joyplot(iris, by="Name", column="SepalWidth", hist=True, bins=20, overlap=0, grid=True, legend=False) – Hoppity81 Nov 23 '21 at 17:50
  • Looking back to this, I realise now I should have asked about plotting density values on the y-axis of a joypy kde plot, not count. Is there any way to do this? Someone else has asked a similar question here: https://stackoverflow.com/questions/65965564/pandas-histogram-plot-with-y-axis-or-colorbar – Hoppity81 Feb 03 '22 at 16:51
  • Wouldn't that be just `joypy.joyplot(..., hist=False)` in the answer below? Or `sns.displot(..., kind='kde')`? – JohanC Feb 03 '22 at 17:17

2 Answers2

1

You could add a secondary y axis with a no-op function:

import joypy
import pandas as pd
from sklearn import datasets

data = datasets.load_iris()
iris = pd.DataFrame(data['data'], columns=data["feature_names"])

fig, axes = joypy.joyplot(iris, overlap=False, hist=True, bins=20)
for ax in axes[:-1]:  # last axis is just for global settings
    ax.secondary_yaxis('right', functions=(lambda x:x, lambda x:x))

enter image description here

Stef
  • 28,728
  • 2
  • 24
  • 52
1

joypy.joyplot can not easily be adapted. For example, the first y-tick of each subplot is used for the name. Also, a dummy subplot is used just for the common x-axis.

An alternative could be to use Seaborn which offers easier options for customization. See for example Seaborn's ridgeplot example.

Here is a start for adapting the joyplot. (It uses seaborn's iris dataset for easier reproducibility.)

from matplotlib import pyplot as plt
from matplotlib.ticker import MaxNLocator, ScalarFormatter
import seaborn as sns  # for the iris dataset
import joypy

iris = sns.load_dataset('iris')
fig, axes = joypy.joyplot(iris, by="species", column="sepal_width", hist=True, bins=20, overlap=0, grid=True,
                          legend=False)
for ax in axes[:-1]:
    ax.set_ylabel(ax.get_yticklabels()[0].get_text())
    ax.yaxis.set_major_locator(MaxNLocator())
    ax.yaxis.set_major_formatter(ScalarFormatter())
fig.subplots_adjust(left=0.1)

joyplot with y-axis for histograms

Here is a somewhat similar Seaborn plot.

from matplotlib import pyplot as plt
import seaborn as sns

iris = sns.load_dataset('iris')
sns.set_style("ticks", {'axes.grid': True})
g = sns.displot(data=iris, row='species', kind='hist', x="sepal_width", height=2, aspect=3)

seaborn sns.displot

JohanC
  • 71,591
  • 8
  • 33
  • 66