Seaborn heatmap colors are reversed - pandas

I'm generating a heatmap from a pandas dataframe using a code that looks like this on my apple computer.
import matplotlib.pyplot as plt
import seaborn as sns
fig, ax = plt.subplots(figsize=(14,14))
sns.set(font_scale=1.4)
sns_plot = sns.heatmap(df, annot=True, linewidths=.5, fmt='g', ax=ax).set_yticklabels(ax.get_yticklabels(), rotation=0)
ax.set_ylabel('Product')
ax.set_xlabel('Manufacturer')
ax.xaxis.set_ticks_position('top')
ax.xaxis.set_label_position('top')
fig.savefig('output.png')
And I get a heatmap looking like this:
I then put my code in a docker container with an ubuntu image and I install the same version of seaborn. The only difference is that I need to add a matplotlib configuration so that TCL doesn't scream:
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import seaborn as sns
And I get a heatmap that looks like this (I use the same code and the same pandas dataframe):
I'm unable to find why the color gradient is inverted and would love to hear if you have any idea.
Thank you !

The default colormap has changed to 'rocket' for sequential data with 0.8 release of seaborn, see the release notes. The colormap looks this way now:
You can always use the cmap argument and specify which colormap you prefer to use. For example, to get the pre-0.8 colormap for non-divergent data use: cmap=sns.cubehelix_palette(light=.95, as_cmap=True).

Related

How to change bars' outline width in a displot?

I managed to make a displot as I intended with seaborn and the only thing I want to change is the bars' outline width. Specifically, I want to make it thinner. Here's the code and a sample of how the dataframe is composed.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
data_final = pd.merge(data, data_filt)
q = sns.displot(data=data_final[data_final['cond_state'] == True], y='Brand', hue='Style', multiple='stack')
plt.title('Sample of brands and their offering of ramen styles')
I'm specifying that the plot should only use rows where the cond_state is True. Here is a sample of the data_final dataframe.
Here is how the plot currently looks like.
I've tried various ways published online, but most of them use the deprecated distplot instead of displot. There also doesn't seem to be a parameter for changing the bars' outline width in the seaborn documentation for displot and FacetGrid
The documentation for the seaborn displot function doesn't have this parameter listed, but you can pass matplotlib axes arguments, such as linewidth = 0.25, to the seaborn.displot function to solve your problem.

seaborn "kde jointplot" doesn't have color mapping in the latest version (0.11.0)

I was running seaborn ver. 0.10.1 on my jupyter notebook. This morning I upgraded to the latest version 0.11.0. Now, my kde jointplot doesn't give the color mapping that it used to. The code is the same. Only the versions are different.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib notebook
np.random.seed(1234)
v1 = pd.Series(np.random.normal(0,10,1000), name='v1')
v2 = pd.Series(np.random.normal(60,15,1000), name='v2')
v3 = pd.Series(2*v1 + v2, name='v3')
# set the seaborn style for all the following plots
sns.set_style('white')
sns.jointplot(v1, v3, kind='kde', space=0);
The function kdeplot (which is used internally by jointplot()to draw the bivariate density plot) has been extensively changed in v.0.11. See What's new and the documentation.
You now have to pass fill=True to get a filled KDE, and you need to specify thresh=0 if you want to fill the available space with color.
sns.jointplot(x=v1, y=v3, kind='kde', space=0, fill=True, thresh=0, cmap='Blues');

how to prevent seaborn to skip year in xtick label in Timeseries Plot

I have included the screenshot of the plot. Is there a way to prevent seaborn from skipping the xtick labels in timeseries data.
Most seaborn functions return a matplotlib object, so you can control the number of major ticks displayed via matplotlib. By default, matplotlib will auto-scale, which is why it hides some year labels, you can try to set the MaxNLocator.
Consider the following example:
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# load data
df = sns.load_dataset('flights')
df.drop_duplicates('year', inplace=True)
df.year = df.year.astype('str')
# plot
fig, ax = plt.subplots(figsize=(5, 2))
sns.lineplot(x='year', y='passengers', data=df, ax=ax)
ax.xaxis.set_major_locator(plt.MaxNLocator(5))
This gives you:
ax.xaxis.set_major_locator(plt.MaxNLocator(10))
will give you
Agree with answer of #steven, just want to say that methods for xticks like plt.xticks or ax.xaxis.set_ticks seem more natural to me. Full details can be found here.

Why does the Seaborn color palette not work for Pandas bar plots?

An online Jupyter notebook demonstrating the code and showing the color differences is at:
https://anaconda.org/walter/pandas_seaborn_color/notebook
The colors are wrong when I make bar plots using Pandas dataframe method. Seaborn improves the color palette of matplotlib. All plots from matplotlib automatically use the new Seaborn palette. However, bar plots from Pandas dataframes revert to the non-Seaborn colors. This behavior is not consistent, because line plots from Pandas dataframes do use Seaborn colors. This makes my plots appear to be in different styles, even if I use Pandas for all my plots.
How can I plot using Pandas methods while getting a consistent Seaborn color palette?
I'm running this in python 2.7.11 using a conda environment with just the necessary packages for this code (pandas, matplotlib and seaborn).
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.DataFrame({'y':[5,7,3,8]})
# matplotlib figure correctly uses Seaborn color palette
plt.figure()
plt.bar(df.index, df['y'])
plt.show()
# pandas bar plot reverts to default matplotlib color palette
df.plot(kind='bar')
plt.show()
# pandas line plots correctly use seaborn color palette
df.plot()
plt.show()
Credit to #mwaskom for pointing to sns.color_palette(). I was looking for that but somehow I missed it hence the original mess with prop_cycle.
As a workaround you can set the color by hand. Note how the color keyword argument behaves differently if you are plotting one or several columns.
df = pd.DataFrame({'x': [3, 6, 1, 2], 'y':[5, 7, 3, 8]})
df['y'].plot(kind='bar', color=sns.color_palette(n_colors=1))
df.plot(kind='bar', color=sns.color_palette())
My original answer:
prop_cycle = plt.rcParams['axes.prop_cycle']
df['y'].plot(kind='bar', color=next(iter(prop_cycle))['color'])
df.plot(kind='bar', color=[x['color'] for x in prop_cycle])
This was a bug in pandas specifically for bar plots (and boxplots as well I think), which is fixed in pandas master (see the reported issue and the PR to fix it).
This will be in pandas 0.18.0 which will be released in the coming weeks.

X-axis labels on Seaborn Plots in Bokeh

I'm attempting to follow the violin plot example in bokeh, but am unable to add x-axis labels to my violins. According to the Seaborn documentation it looks like I should be able to add x-axis labels via the "names" argument, however, the following code does not add x-axis labels:
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from bokeh import mpl
from bokeh.plotting import show
# generate some random data
data = 1 + np.random.randn(20, 6)
# Use Seaborn and Matplotlib normally
sns.violinplot(data, color="Set3", names=["kirk","spock","bones","scotty","uhura","sulu"])
plt.title("Seaborn violin plot in Bokeh")
# Convert to interactive Bokeh plot with one command
show(mpl.to_bokeh(name="violin"))
I believe that the issue is that I'm converting a figure from seaborn to matplotlib to bokeh, but I'm not sure at what level the x-axis labels go in.
I've confirmed that the labels are showing up in matplotlib before conversion to bokeh. I've also tried adding the labels to bokeh after conversion, but this results in a weird plot. I've created an issue for this problem with the bokeh developers here.
Since Bokeh 12.5 (April 2017), support for Matplotlib has been deprecated, so mpl.to_bokeh() is no longer available.