Giter Club home page Giter Club logo

joypy's Introduction

JoyPy

PyPI version python version build status License: MIT Downloads

JoyPy is a one-function Python package based on matplotlib + pandas with a single purpose: drawing joyplots (a.k.a. ridgeline plots).

A joyplot.

The code for JoyPy borrows from the code for kdes in pandas.plotting, and uses a couple of utility functions therein.

What are joyplots?

Joyplots are stacked, partially overlapping density plots, simple as that. They are a nice way to plot data to visually compare distributions, especially those that change across one dimension (e.g., over time). Though hardly a new technique, they have become very popular lately thanks to the R package ggjoy (which is much better developed/maintained than this one -- and I strongly suggest you use that if you can use R and ggplot.) Update: the ggjoy package has now been renamed ggridges.

Why are they called joyplots?

If you don't know Joy Division, you are lucky: you can still listen to them for the first time! Here's a hint: google "Unknown Pleasures". This kind of plot is now also known as ridgeline plot, since the original name is controversial.

Documentation and examples

JoyPy has no real documentation. You're strongly encouraged to take a look at this jupyter notebook with a growing number of examples. Similarly, github issues may contain some wisdom :-)

A minimal example is the following:

import joypy
import pandas as pd

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

By default, joypy.joyplot() will draw joyplot with a density subplot for each numeric column in the dataframe. The density is obtained with the gaussian_kde function of scipy.

Note: joyplot() returns n+1 axes, where n is the number of visible rows (subplots). Each subplot has its own axis, while the last axis (axes[-1]) is the one that is used for things such as plotting the background or changing xticks, and is the one you might need to play with in case you want to manually tweak something.

Dependencies

  • Python 3.5+
    Compatibility with python 2.7 has been dropped with release 0.2.0.

  • numpy

  • scipy >= 0.11

  • matplotlib

  • pandas >= 0.20 Warning: compatibility with pandas >= 0.25 requires joypy >= 0.2.1

Not sure what are the oldest supported versions. As long as you have somewhat recent versions, you should be fine.

Installation

It's actually on PyPI, because why not:

pip install joypy

To install from github, run:

git clone [email protected]:leotac/joypy.git
cd joypy
pip install .

License

Released under the MIT license.

Disclaimer + contributing

This is just a sunday afternoon hack, so no guarantees! If you want to contribute or just copy/fork, feel free to.

joypy's People

Contributors

eointravers avatar johnrsibert avatar leotac avatar yaront avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

joypy's Issues

it seems sequence of packages importing is matter

I have tried

import joypy
import matplotlib.pyplot as plt

and see no result.
but when I have flipped sequence

import matplotlib.pyplot as plt
import joypy

it starts work. Btw there won't be any warning or errors. just empty jupyter cell result

reorder the axes within the figure

Currently the axes are ordered from low to high from top to bottom respectively. Is there a way to reverse this order? Or specify a custom order?

if you reverse data on line 390:

for i, group in enumerate(data[::-1]):

And reverse labels on line 444:

_setup_axis(a, global_x_range, col_name=labels[::-1][i], grid=ygrid)

It will reverse the order. But this seems a bit hacky, maybe there is a better way to do it?

Provide aggregated data instead of detail?

Hi,

Is it possible to provide aggregated data to joyplot function ?

When working on big volume of data, we can not manipulate the unitary data in Python, so I would like to retrieve myself the number of occurrence (using database SQL aggregation) and send to joyplot the resulting aggregated table.

Could you please tell me how I can achieve that ?

Thank you.

Remi

Data with gap

I have a time series ranging from 1945 to 1990 that doesn't has two years (1954 and 1976). I want to do a joyplot with this time series but I'm getting the following message: "ValueError: dataset input should have multiple elements". How could I solve this?

Thank you so much.

Joypy and gridspec

I'd like to add a plot, side-by-side the joyplot, showing all of the distributions on one plot. I am successful at doing that, but something is weird with the xticks. I've been looking through the code at how the xticks are set and I don't see why what is in your package would be wrong.

The problem can be seen in the figure below. It looks like the xticks are being set relative to the figure size and not the last axes instance. Would you happen to know what's going on here? Because I sure don't. Any thoughts would be appreciated.

The figure:
download

The code:

from scipy.stats import gaussian_kde
import numpy as np
import pandas as pd
from sklearn import datasets

import joypy
import matplotlib.gridspec as gridspec
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.colors import rgb2hex

iris = datasets.load_iris()
df=pd.DataFrame(iris.data,columns=iris.feature_names)

fig = plt.figure(dpi=300)
gs = fig.add_gridspec(nrows=4, ncols=2)

ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[1, 0])
ax3 = fig.add_subplot(gs[2, 0])
ax4 = fig.add_subplot(gs[3, 0])

ax5 = fig.add_subplot(gs[:, 1])

axes = [ax1, ax2, ax3, ax4]
joypy.joyplot(df, ax=axes, colormap=cm.autumn_r, linewidth=0.5)

limits = ax1.get_xlim()
x = np.arange(limits[0], limits[1], 0.01)
ncols = len(df.columns)

for i, (col, vals) in enumerate(df.items()):
    gkde = gaussian_kde(vals, bw_method=None)
    y = gkde.evaluate(x)
    ax5.plot(x, y, lw=0.5, color='k')
    ax5.fill_between(x, y, color=rgb2hex(cm.autumn_r(i / ncols)))

Entering the name of a non-numeric column raises "min() arg is an empty sequence"

If you enter the name of a column which corresponds to non-numeric data, the error message given is:

~/miniconda3/lib/python3.6/site-packages/joypy/joyplot.py in _joyplot(data, grid, labels, sublabels, xlabels, xlabelsize, xrot, ylabelsize, yrot, ax, figsize, hist, bins, fade, xlim, ylim, fill, linecolor, overlap, background, range_style, x_range, tails, title, legend, loc, colormap, color, **kwargs)
    352     else:
    353         global_x_range = _x_range(x_range, 0.0)
--> 354     global_x_min, global_x_max = min(global_x_range), max(global_x_range)
    355 
    356     # Each plot will have its own axis

ValueError: min() arg is an empty sequence

This was encountered when trying to make plots of datetime values. The error message is not informative that the error is due to datetime not being a numeric type. Perhaps in _grouped_df_to_standard, when you check if the column is numeric, you can throw a warning or error if there are no numeric columns returned.

Calling `xlim` has unexpected effect

If you create a joyplot, and then subsequently set the xlimits by calling matplotlib.pyplot.xlim(xmin, xmax), the x-axis labels shift but the data does not shift to reflect the new x range.

This can easily lead to incorrectly plotted data because no warning is given -- the axis labels just stop reflecting the actual data.

For instance, below is the exact same data plotted with joyplot, but in the first case there was a subsequent call to xlim to set a narrower xrange and in the second case there was not. As you can see, the xticks shifted but not the data.

I'm guessing the preferred way to set the xlimits is instead via the xrange parameter of joyplot, but I still worry the behavior described in this issue could easily lead to incorrect plots.

screen shot 2017-11-24 at 8 15 40 am

Different issue on import for 0.1.4

I saw the other import error in the solved issues, but this one is different. I'm using Pandas 0.20.3

File "myscript.py", line 17, in <module>
import joypy
File "/home/user/anaconda2/lib/python2.7/site-packages/joypy/init.py", line 1, in
from .joyplot import joyplot, plot_density, _joyplot
File "/home/user/anaconda2/lib/python2.7/site-packages/joypy/joyplot.py", line 221
raise ValueError("At least a column/group haNo numeric values found. Joyplot requires at least a numeric column/group.")

Transparency doesn't work outside of fade=True

The alpha channel of color=(r,g,b,a) doesn't get passed to fill_between because of group_alpha = _get_alpha(i, num_axes) if fade else 1 on line 381. Adding an intermediate check and setting group_alpha to the alpha channel of color if it exists, should fix it.

Specify the order of groups

Hi, I am using Joypy, and it is very useful to compare the distributions of different groups.

Now I would like to make my plot clearer by ordering the groups so that their distributions show a shift from the left to the right. Is it possible to do this?

Thank you !

Creating subplots with joypy

Thanks for the great library @Sbebo !!

I am struggling a little bit on dynamically creating subplot using joypy:

import joypy
import pandas as pd
from matplotlib import cm
import matplotlib.pyplot as plt

f, a = plt.subplots(2, 1)
data = pd.read_csv('../data.txt', sep="\t", header=None)

for c, i in enumerate(range(0, len(data), 50)):
    x_range = list(range(i, i+50, 1))
    fig, axes = joypy.joyplot(data[i:i+50], kind="values", x_range=x_range, colormap=cm.Set2,
                             figsize=(100,10))
    **a[c] = f.add_subplot(fig) # this is wrong! Though I can't figure out how to add joyplot as subplot to my figure..**
    a[c].set_xticks(x_range);

f.savefig('joyplot.png', bbox_inches='tight') 

Any suggestions would be appreciated! Thanks!

Incorrect plotting of standard gaussian?

import numpy as np
from scipy.stats import norm
import joypy
joypy.joyplot([norm.pdf(np.linspace(-10,10))]);

produces:

image

Why would there be a hump towards the right? Why would it be cut off towards the left?

"By" Column Is Not Properly Removed

I created a column key to print different groups of my dataset. However, the key is still present in the histograms (orange bars).

import joypy
from sklearn.datasets import load_iris

df = load_iris(as_frame=True).data
df["key"] = df.index % 3
df = df[["sepal length (cm)", "key"]]
_ = joypy.joyplot(df, by="key", hist=True)

image

pandas.plotting._tools not supported in pandas 0.25.0

I have not extensively tested this, but it seems the

from pandas.plotting._tools import (_subplots, _flatten)

does not work in the new pandas (0.25.0, released July 18th)

Error is:
from pandas.plotting._tools import (_subplots, _flatten)
ModuleNotFoundError: No module named 'pandas.plotting._tools'

The code works perfectly fine in pandas 0.24.2

Getting y values of each subplot

Is there a way to get the y values of each subplot? I would like to plot several vertical lines corresponding to different quantities (for example, mean) and would like the line to go from the bottom of the plot up to the "top edge" of the plot (i.e. the y value).

For example, in the plot below I wanted to plot the mean but the vertical overshoots to plot (because I plotted until y=1)

image

Unexpected behaviour of figsize and overlap

Hi @Sbebo,
Thanks very much for the fantastic module. I encountered a strange behaviour when trying to control figsize and overlap, which I assume is a bug. Here's a minimum code example:

# load modules and create a list of random data
import numpy as np
import joypy as jp

dist_list = []
for i in range(20):
    dist_list.append(np.random.normal(loc=np.random.random(), size=100))

With these arguments the plot is created normally:

fig, ax = jp.joyplot(dist_list, overlap=1, figsize=(8,3.3))
fig.show()

image

But for any height value of figsize that is higher than 3.3 in this case, all density plots appear extremely flattened, and changing the overlap has no effect at all:

fig, ax = jp.joyplot(dist_list, overlap=1, figsize=(8,3.4))
fig.show()

image

I noticed this when working on some larger data, and the "threshold" of this sudden change was at a different value for the height of figsize
Is there a way to have a larger figure but prevent this from happening?
Thanks!

import fails with latest version of pandas

import joypy throws

---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-2-47a753585c6f> in <module>
----> 1 import joypy
      2 import numpy as np
      3 import pandas as pd
      4 import matplotlib.pyplot as plt
      5 from sklearn.linear_model import LinearRegression

~/.local/lib/python3.6/site-packages/joypy/__init__.py in <module>
      3 __version__ = '0.1.10'
      4 
----> 5 from .joyplot import joyplot, plot_density, _joyplot

~/.local/lib/python3.6/site-packages/joypy/joyplot.py in <module>
      2 
      3 import numpy as np
----> 4 from pandas.plotting._tools import (_subplots, _flatten)
      5 import os
      6 import matplotlib as mpl

ModuleNotFoundError: No module named 'pandas.plotting._tools'

Use log transformed x-axis

Thanks for this nice package. I'm looking for a way to use a log10 transformation on the x-axis, and still display the 'right' values as ticklabels.

Things work fine with np.log10 transforming my input data, but then the tick labels don't make sense.

I tried

fig, ax = joypy.joyplot(mydata)
ax.set_xscale('log')

which throws an error because apparently ax is a list, so I tried:

for a in ax:
    a.set_xscale('log')

which throws a ValueError because ValueError: Data has no positive values, and therefore can not be log-scaled.

Do you have suggestions?

'Cycler' object has no attribute 'by_key'

Hi,
I am running the demo from the notebook:

from future import unicode_literals
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")
%matplotlib inline
fig, axes = joypy.joyplot(iris)

and I get this error:
Traceback (most recent call last):
File "", line 1, in
TypeError: 'DataFrame' object is not callable

fig, axes = joypy.joyplot(iris)
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python2.7/dist-packages/joypy/joyplot.py", line 237, in joyplot
**kwds)
File "/usr/local/lib/python2.7/dist-packages/joypy/joyplot.py", line 433, in _joyplot
element_color = _get_color(i, num_axes, j, num_subgroups)
File "/usr/local/lib/python2.7/dist-packages/joypy/joyplot.py", line 358, in _get_color
return plt.rcParams['axes.prop_cycle'].by_key()['color'][j]
AttributeError: 'Cycler' object has no attribute 'by_key'

I am using the latest update and I am using Python 2.7 from Ubuntu

It should be possible to sort the plots

Lets say you do something like this:

fig, axes = joypy.joyplot(df, by="company", column="Score")

This will produce multiple graphs, sorted by the column "company". "company" would be sorted alphabetically by default, but what if I want a custom sort of how the graph are shown?

For example to have something like this:
MXT8U

Can't install via pip

" Could not find a version that satisfies the requirement joypy (from versions: )
No matching distribution found for joypy"

Is it possible to inverse the plot?

Is it possible to inverse the plot
eg:
image

Above is plotted by Target Field and each predictors on same line, if there are many features the plot looks too clustered.

Is it possible to split plot by predictors and each line showing target distribution, like the ggridges in R

ggplot(gather.data.train,aes(y = variable, fill = Target, x = value, alpha=0.4)) +  geom_density_ridges(scale = 5)

image
Thanks

Can't get colormap to work properly

I'm trying to make a joyplot and when I set colormap=cm.autumn_r , my plot only uses the first color in the colormap. I wanted to use cm.tab20c and I eventually got it working by hacking the _get_color function to return colormap(i % len(colormap.colors)) . I don't think this is the right general solution but I'm not sure what to fix before submitting a pull request. Any ideas what might be going wrong? I think there might also be some weird interaction between gradient and named-color colormaps too.

Also, this package is amazing! Thank you so much for putting it together.

Source files on PyPI

Ciao Leonardo,
I was planning to submit your package to conda-forge, such that it's installable using conda (since I want to put one of my packages there and yours is a dependency).

Would you mind to please put the source files of joypy on PyPI , too, i.e. submit the tar.gz next to the wheel? That would be great. Thanks!

Cheers,
Simon

Passing `ax` ignores axis and uses entire plot

When I do the following:

from sklearn import datasets
from joypy import joyplot

iris = datasets.load_iris()
iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)
fig, axes = plt.subplots(ncols=2, figsize=(12, 4))
joyplot(iris_df, ax=axes[0])
joyplot(iris_df, ax=axes[1])

I expect to get two of the same plot, side by side. Instead, I get one plot that takes up the entire figure. So it appears joyplot is ignoring the Axis being passed in.

Versions:

python==3.6.1
joypy==0.1.7
scipy==1.0.0
numpy==1.13.3
matplotlib=2.1.1

Aggregate data in a specific column

Hi,

I saw #17 explaining how to use kind="values and x_range in order to use aggregated data, but I'm finding it hard to combine this functionality with setting a specific column for output.
I've got a dataset with a set of locations (lat & long) with measurements taken at each point giving a numerical value.

     lat        long        val

    001.012    001.01        11

    001.431    004.49        25

    001.769    008.72        04

    002.100    001.32        03

    002.504    003.49        17

    ...

(rubbish formatting but it gives you the right idea)

I've binned the y-values (lat) using pd.cut to give a lat_bins column and plotted this using:

fig, axes = jp.joyplot(df, by="lat_bins", column="long")

But what I'd like to have is something like:

fig, axes = jp.joyplot(df, by="lat_bins", column="long", kind="values", x_range=<some range>))

This displays a plot without any data; and no error appears when running the code so I don't know what to fix. The goal is to have a plot at each latitude showing the distribution according to longitude. (i.e., the dataset shown above would have the first layer showing 11 - 25 - 4 going across from 001 to 008 lat.

Typo in "num_axes" variable?

Line 408:
legend_axis = num_axis - 1 --> undefined name 'num_axis'

is that supposed to be 'num_axes' which is defined in Line 392?

ENH: Add logscale option

It'd be nice to plot with logarithmic scale. I think this could be achieved by computing kde etc on log-transformed data and transforming back and using log axis scale.

I'm not sure if I'm alone in wanting this, but it'd be nice. I'm open to discussion and potential PR myself.

AttributeError: module 'joypy' has no attribute 'joyplot'

Hi @Sbebo ,

I was trying to implement Joyplots on my data frame in python. After importing joypy, when I try to use joyplot I can the following attribute error.

AttributeError: module 'joypy' has no attribute 'joyplot'

Any help will be great!
Hope to hear from you soon.

Rotate ridges 90 degrees?

Hi @Sbebo, thanks for a great package. Curious if it is possible to rotate the ridges 90 degrees to make ridges vertical? E.g. seaborn's kde plot has an argument called 'vertical' that can be set with vertical = True. Tried to pass that through kwds but no luck.

One more example!

Just a comment:

how about inserting in the HowTo section an example which does not involve the use of data frames?
Let's say I have such data

x = np.arange(0,100)

x= np.arange(0,100,0.1)
y =[]
for i in range(1,5):
y.append(x**2)

how shall I use Joyplot with x and y?

Thanks!

Wrong colors in legend for histograms

See example.

import joypy
import pandas as pd
from matplotlib import pyplot as plt

iris = pd.read_csv("data/iris.csv")
fig, axes = joypy.joyplot(iris, by="Name", hist=True, overlap=0, legend=True)

image

Titles in X and Y axis

Hi, I have a question about Y labels and believe this functionality exists, but I cannot get it right. E.g.: I can put Y axis labels on every subplot something like this:

fig, axes = joyploy(...)
for ax in axes:
    ax.set_ylabel("mylab")

This creates a label for every density plot. Can I somehow add a "global" Y axis label, instead of a Y axis label for every subplot. I suppose I can do that by providing an ax argument to joyploy, but it does not seem to work.

Thanks for your help,
Simon

Update Iris Example in Readme

Hi, I propose this minimal working example for the Readme, as users will probably have sklearn already installed anyways:

import joypy
from sklearn.datasets import load_iris

iris = load_iris(as_frame=True).data
fig, axes = joypy.joyplot(iris)

`LinAlgError: singular matrix` with data having all mass at 0 for some steps

I get a LinAlgError: singular matrix when attempting to plot a joyplot on data that has groups with all zeros (i.e. all mass at exactly 0). It seems this is an issue from the direct pass-through to the kde estimator and ultimately comes from trying to take the inverse of a singular covariance matrix. While one could argue that is reasonable expected behavior, I feel a better default in this situation would be to plot a vertical line at x = 0, y = 1 (no tails). You can reproduce the described error via:

from joypy import joyplot
df = pd.DataFrame({
    'value': np.concatenate([np.random.uniform(0, 1, size=100), np.random.uniform(0.5, 1, size=100), np.zeros(100)]),
    'time': np.concatenate([np.zeros(100), np.ones(100), np.ones(100) * 2]).astype(int)
})
joyplot(df, by='time', columns=['value'])

Versions:

python==3.6.1
joypy==0.1.7
scipy==1.0.0
numpy==1.13.3
matplotlib=2.1.1

The exact error message is:

---------------------------------------------------------------------------
LinAlgError                               Traceback (most recent call last)
<ipython-input-14-35fa7743dda5> in <module>()
----> 1 joyplot(df, by='time', columns=['value'])

/Users/mack/anaconda2/envs/py3k/lib/python3.6/site-packages/joypy/joyplot.py in joyplot(data, column, by, grid, xlabelsize, xrot, ylabelsize, yrot, ax, figsize, hist, bins, fade, ylim, fill, linecolor, overlap, background, labels, xlabels, ylabels, range_style, x_range, title, colormap, **kwds)
    233                     title=title,
    234                     colormap=colormap,
--> 235                     **kwds)
    236
    237 ###########################################

/Users/mack/anaconda2/envs/py3k/lib/python3.6/site-packages/joypy/joyplot.py in _joyplot(data, grid, labels, sublabels, xlabels, xlabelsize, xrot, ylabelsize, yrot, ax, figsize, hist, bins, fade, xlim, ylim, fill, linecolor, overlap, background, range_style, x_range, tails, title, legend, loc, colormap, color, **kwargs)
    437                              fill=fill, linecolor=linecolor, label=sublabel,
    438                              zorder=element_zorder, color=element_color,
--> 439                              bins=bins, **kwargs)
    440
    441

/Users/mack/anaconda2/envs/py3k/lib/python3.6/site-packages/joypy/joyplot.py in plot_density(ax, x_range, v, kind, bw_method, bins, fill, linecolor, clip_on, **kwargs)
    248
    249     if kind == "kde":
--> 250         gkde = gaussian_kde(v, bw_method=bw_method)
    251         y = gkde.evaluate(x_range)
    252     elif kind == "counts":

/Users/mack/anaconda2/envs/py3k/lib/python3.6/site-packages/scipy/stats/kde.py in __init__(self, dataset, bw_method)
    170
    171         self.d, self.n = self.dataset.shape
--> 172         self.set_bandwidth(bw_method=bw_method)
    173
    174     def evaluate(self, points):

/Users/mack/anaconda2/envs/py3k/lib/python3.6/site-packages/scipy/stats/kde.py in set_bandwidth(self, bw_method)
    497             raise ValueError(msg)
    498
--> 499         self._compute_covariance()
    500
    501     def _compute_covariance(self):

/Users/mack/anaconda2/envs/py3k/lib/python3.6/site-packages/scipy/stats/kde.py in _compute_covariance(self)
    508             self._data_covariance = atleast_2d(np.cov(self.dataset, rowvar=1,
    509                                                bias=False))
--> 510             self._data_inv_cov = linalg.inv(self._data_covariance)
    511
    512         self.covariance = self._data_covariance * self.factor**2

/Users/mack/anaconda2/envs/py3k/lib/python3.6/site-packages/scipy/linalg/basic.py in inv(a, overwrite_a, check_finite)
    974         inv_a, info = getri(lu, piv, lwork=lwork, overwrite_lu=1)
    975     if info > 0:
--> 976         raise LinAlgError("singular matrix")
    977     if info < 0:
    978         raise ValueError('illegal value in %d-th argument of internal '

LinAlgError: singular matrix

How to align all y_series?

I would like to do an animation over time. Basically produce multiple joyplots (filtering the data by a date range) and then merge them into a GIF. Basically seeing the distribution change over time.

My problem right now is that if I use ylim='own' (which is the look I like), the ordering of the y axis change all the time between my plots. Using ylim='max', the graphs are super small.

But, if I set a fixed ylim=[0,100], then the y axis is always the same and the y labels align between images, but sometimes the data is clipped at the top.

What would you recommend for a scenario like that?

Verbose warning on import regarding `matplotlib.use()` call.

I get the following warning when importing after importing matplotlib.pyplot. Seems to be caused by the call to mpl.use('Agg') in imports section of joyplot.py. This doesn't inhibit any functionality, but it is a huge eye-sore. I'm not sure what the motivation was for that call and I noticed an environment variable being checked before calling. I get this warning in an IPython notebook. Perhaps there is an additional check to perform there to prevent this?

joyplot.py:9: UserWarning:
This call to matplotlib.use() has no effect because the backend has already
been chosen; matplotlib.use() must be called before pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.
...

Color gradient along horizontal axis rather than the vertical axis

It seems joypy was used to create this prominent figure copied below: https://ichef.bbci.co.uk/news/1536/cpsprodpb/1216F/production/_132259047_global_temp_delta_1991_2020avg_multiple_ridges_v2-2x-nc.png.webp

In it, the colormap gradient runs along the horizontal axis of each individual filled KDE plot, rather than along the vertical axis which is what happens by default when you pass a colormap into joyplot. How can you achieve this with joypy.joyplot?

image

Colourmap depending upon a third variable or passing a list of colors

I created this joyplot below
D9-y6IhUIAAQvLzpng

However, for every one of the 20 teams on the y-axis, I want to colour them according to a Pandas dataframe column which contains a total value for every team. I was wondering if the colourmap could be customised to colour the plots according to a third data variable - either a Pandas Series, numpy array, or something similar.
So for my dataframe the Total would look like this:

   Team     Total
Angers      356
Monaco      452
PSG         501
Lyon        369

Here's what works as expected:

fig, axes = joypy.joyplot(df, by="Team", column="Minute", figsize =(10,16), x_range = [0,94], linewidth = 1,
legend=False, colormap = color ,  title= "When do teams in Ligue 1 take their shots?")

Here are a few solutions I tried and failed at. Firstly, I created a colormap for the entire series depending on the Total data using this -

norm = plt.Normalize(group_df["Total"].min(), group_df["Total"].max())
cmap = plt.cm.viridis
sm = matplotlib.cm.ScalarMappable(cmap=cmap, norm=norm)
ar = np.array(group_df["Total"])
Cm = cmap(norm(ar))
sm.set_array([])

1 - Passing the customised colourmap in the function

fig, axes = joypy.joyplot(df, by="Team", column="Minute", figsize =(10,16), x_range = [0,94], linewidth = 1,
legend=False, colormap = Cm ,  title= "When do teams in Ligue 1 take their shots?")

2 - Passing the array of RGBA tuples to the colour

color = np.array(tuple(map(tuple,Cm)))
fig, axes = joypy.joyplot(df, by="Team", column="Minute", figsize =(10,16), x_range = [0,94], linewidth = 1,
legend=False, color = color ,  title= "When do teams in Ligue 1 take their shots?")

3 - Using the axes handles to set_facecolor - I saw this here

for col, ax in zip(Cm, axes):
        ax.patch.set_facecolor(col)

1 and 2 threw up an invalid RGBA argument and Assertion Error respectively. 3 had no error but the change was not reflected in the resulting plot. All I could gather is that currently, there's a no way to pass a list of colors (with a size similar to the grouped y-axis) or a customised colormap. If that's true, does there exist a work-around which I could implement? Or could a new feature be added?

Github Tags/Releases?

Hi,

The latest tag on github here is still 0.2.2 whilst the version has progressed to 0.2.5.
Actually, I maintain this package in debian, and we take the source package from github (not pypi for several reasons) and hence it'd
be very helpful if you could propagate the missing tag(s) (at least the latest one)

Could you please push the relevant tag?

=============================================================================================

CC: @leotac

How to group/separate?

I exactly would like to create a plot like https://www.machinelearningplus.com/wp-content/uploads/2018/11/24_JoyPlot_joypy-min-1024x741.png found on https://www.machinelearningplus.com/plots/top-50-matplotlib-visualizations-the-master-plots-python/ , where they use fig, axes = joypy.joyplot(mpg, column=['hwy', 'cty'], by="class", ylim='own', figsize=(14,10))

To do so I use fig, ax = joypy.joyplot(Temperatures_df, by="Transformer", figsize=(14,7), linewidth=0.05,overlap=3,colormap=cm.OrRd_r)
but I receive the following:

plot

but I would like to have the variables separated and then each variable grouped by "Transformer". Hence, I tried fig, ax = joypy.joyplot(Temperatures_df, figsize=(14,7), linewidth=0.05,overlap=3, colormap=cm.OrRd_r) but then I receive:
plot1

What I am actually looking for is a combination of both of them. Respectively I don't understand why I can't create the same appearance like in the first image as this fulfills my expectations already.
Why is that?

The Temperatures_df looks like following:

BotTmp | EnvTmp | HPTmpClc | LTCTmp | Transformer
timestamp

2018-02-02 14:31:00 | NaN | NaN | 54.400000 | NaN | Transformer S1
2018-02-02 14:45:00 | NaN | NaN | 54.400000 | NaN | Transformer S1
2018-02-02 15:00:00 | NaN | NaN | 54.400000 | NaN | Transformer S1
(...)
2018-10-25 01:30:00 | NaN | NaN | NaN | 30.790190 | Transformer S2

Passing axis parameter into new joyplot function call?

Hi!

I'm using joyplot with raw data (loving it so far). Attached are two figures I've produced. I would like to pass the axis generated from the first one as an argument into the second, in order to plot them on the same figure. However, I get the error below. Is there an easy work-around, without putting everything into dataframes?
Screen Shot 2022-03-30 at 11 59 38 AM
Screen Shot 2022-03-30 at 12 00 17 PM
Screen Shot 2022-03-30 at 12 01 29 PM

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.