Converting a matplotlib colourmap to a seaborn colour palette - python

I have made a colourmap from my chosen colours, however I'd like to convert it to a palette which can be used to 'hue' a seaborn plot. Is this possible, and if so how so?
I have used...
cmap = pl.colors.LinearSegmentedColormap.from_list("", ["red","white"],gamma=0.5,N=len(hue))
...in order to make my own colourmap, which I know works because it can be applied to a standard matplotlib.pyplot.scatter plot successfully, as shown below.
plt.scatter(x=[1,2,3,4,5],y=[1,2,3,4,5],c=[5,4,3,2,1],cmap=cmap)
click here to see the output as it won't let me embed an image
However, I am trying to use seaborn's swarmplot function and pass in my colourmap as the hue parameter. Obviously this doesn't work as this parameter requires a palette - hence my question!
I'm not quite sure where to start! Any help would be appreciated!

A seaborn palette is a simple list of colors. You may obtain the colors via
cmap(np.linspace(0,1,cmap.N))
Complete example:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import seaborn as sns
df =pd.DataFrame({"x" : np.random.randint(0,4, size=200),
"y" : np.random.randn(200),
"hue" : np.random.randint(0,4, size=200)})
u = np.unique(df["hue"].values)
cmap = mcolors.LinearSegmentedColormap.from_list("", ["indigo","gold"],gamma=0.5,N=len(u))
sns.swarmplot("x", "y", hue="hue", data=df, palette=cmap(np.linspace(0,1,cmap.N)))
plt.show()

Related

How to make any matplotlib colormap a repeating cmap?

I am ploting a map with matplotlib and I need to build a cmap that is like the 'prism' cmap. This cmap is repeating itself a high number of time.
I tried to build a cmap from a list of selected colors, but the colors do not display gradation.
The code I use is:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
cmap = matplotlib.colors.LinearSegmentedColormap.from_list(
"",
np.concatenate([["#fb4747", "#315ace", "#b5f6e5", "#FFB347"] for i in range(40)]))
Now I am trying to build a repeating cmap using another matplotlib colormap. And I really need the shading in the colors. Is there any way to do that?

Random colors by default in matplotlib

I had a look at Kaggle's univariate-plotting-with-pandas. There's this line which generates bar graph.
reviews['province'].value_counts().head(10).plot.bar()
I don't see any color scheme defined specifically.
I tried plotting it using jupyter notebook but could see only one color instead of all multiple colors as at Kaggle.
I tried reading the document and online help but couldn't get any method to generate these colors just by the line above.
How do we do that? Is there a config to set this randomness by default?
It seems like the multicoloured bars were the default behaviour in one of the former pandas versions and Kaggle must have used that one for their tutorial (you can read more here).
You can easily recreate the plot by defining a list of standard colours and then using it as an argument in bar.
colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd',
'#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf']
reviews['province'].value_counts().head(10).plot.bar(color=colors)
Tested on pandas 0.24.1 and matplotlib 2.2.2.
In seaborn is it not problem:
import seaborn as sns
sns.countplot(x='province', data=reviews)
In matplotlib are not spaces, but possible with convert values to one row DataFrame:
reviews['province'].value_counts().head(10).to_frame(0).T.plot.bar()
Or use some qualitative colormap:
import matplotlib.pyplot as plt
N = 10
reviews['province'].value_counts().head(N).plot.bar(color=plt.cm.Paired(np.arange(N)))
reviews['province'].value_counts().head(N).plot.bar(color=plt.cm.Pastel1(np.arange(N)))
The colorful plot has been produced with an earlier version of pandas (<= 0.23). Since then, pandas has decided to make bar plots monochrome, because the color of the bars is pretty meaningless. If you still want to produce a bar chart with the default colors from the "tab10" colormap in pandas >= 0.24, and hence recreate the previous behaviour, it would look like
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
N = 13
df = pd.Series(np.random.randint(10,50,N), index=np.arange(1,N+1))
cmap = plt.cm.tab10
colors = cmap(np.arange(len(df)) % cmap.N)
df.plot.bar(color=colors)
plt.show()

Use a colormap as a palette in Seaborn

This is probably a misunderstanding how colormaps are different from palettes, but I'd like to use a colormap that is not available in seaborn for coloring my binned dataset. I tried using palettable and now cmocean in particular directly but will get a TypeError;
'LinearSegmentedColormap' object is not iterable
Using any of the palettes that are available in Seaborn will work just fine, but I need a palette that doesn't go to white as this adds a weird 'banding' to the plot.
I have a dataframe with 3 columns with numerical data, dimensions and added a bin column for the colors usage in the plot.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import cmocean
cmap=cmocean.cm.balance
cpal=sns.color_palette(cmap,n_colors=64,desat=0.2)
plt.style.use("seaborn-dark")
ax = sns.stripplot(x='Data', y='Dimension', data=dfBalance, jitter=0.15, edgecolor='none', alpha=0.4, size=4, hue='bin', palette=cpal)
sns.despine()
ax.legend_.remove()
plt.show()
Seaborn does not take a Colormap instance as input for .color_palette. It takes
name of matplotlib cmap, [...], or a list of colors in any format matplotlib accepts
Since cmocean registers its colormaps with matplotlib with a "cmo." prefix, you would do
import seaborn as sns
import cmocean
cpal = sns.color_palette("cmo.balance", n_colors=64, desat=0.2)
In case you have a custom colormap created yourself or from any other package, you might register it yourself.
import seaborn as sns
import matplotlib.cm
import matplotlib.colors
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", ["brown", "pink", "limegreen"])
matplotlib.cm.register_cmap("mycolormap", cmap)
cpal = sns.color_palette("mycolormap", n_colors=64, desat=0.2)

How can I convert a seaborn color palette into a cmap?

I would like to convert the continuous diverging color palette "RdBu_r" (or really, any pre-defined color palette) in seaborn into a matplotlib colormap.
This is the closest I've come, but it creates a discrete color map, whereas I would like a continuous map:
import seaborn as sns
from matplotlib.colors import ListedColormap
palette = sns.color_palette("RdBu_r", n=7) # could make n = 100 as a quick fix
cmap = ListedColormap(colors=palette)
cmap.set_bad(color='black', alpha=0.5)
sns.heatmap(cmap=cmap)
Ultimately, I am trying to create a seaborn heatmap with the "RdBu_r" color palette, with null values filled in as dark squares, which is why I am trying to create a cmap with set_bad(color='black'), as opposed to just passing in "RdBu_r" into the cmap argument of sns.heatmap.
Thanks guys.
"RdBu_r" is a matplotlib colormap. There hence seems little reason to convert it to a list of colors first. Instead just use it as it is.
import matplotlib.pyplot as plt
import seaborn as sns
cmap = plt.get_cmap("RdBu_r")
cmap.set_bad(color='black', alpha=0.5)
sns.heatmap(data, cmap=cmap)

Set first element of colormap in matplotlib to gray

How can I change the first color in a listed colormap in matplotlib to gray? I created the colormap as follows:
import matplotlib.pyplot as plt
plt.get_cmap('viridis_r')
Sorry I haven't tested this, but does this work?
>>> col_map = plt.get_cmap('viridis_r')
>>> col_map.__dict__['colors'].insert(0,[0.5,0.5,0.5])

Categories

Resources