My seaborn and Matplotlib plots look the same? - matplotlib

lately people have been telling me that seaborn is the best data visualization package in Python, so I decided to try it out. However, my plots look exactly identical to my matplotlib plots..
I am using PyCharm, Python 3.6.
Here is my super simple code to test the two:
x = [1, 2, 3, 4, 5]
y = [11, 12, 13, 14, 15]
plt.plot(x, y)
plt.show()
sns.lineplot(x, y)
plt.show()
and they both look like:
Normally, seaborn plots should have at leasthave a gridded blue background. Why is mines not working?

Seaborn is an extention to matplotlib, which simplifies certain tasks. I.e. often creating a plot with seaborn takes only 30 to 50% of the number of code lines it would take to plot with matplotlib directly. But every seaborn plot necessarily is a matplotlib plot.
Concerning the style, seaborn has some shortcuts on setting style parameters. Those are explained in detail in the Aestetics tutorial.
In short, you can use
seaborn.set()
to get the "darkgrid" theme; you can use
seaborn.reset_defaults()
to reset the parameters back to the matplotlib defaults.
Essentially[*] the same can be achieved with matplotlib via
plt.style.use("seaborn-darkgrid")
and
plt.style.use("default")
For this read the matplotlib customizing tutorial.
[*] There are small differences, because seaborn.set also sets other parameters like defaults of figure size etc.

maybe I am a little too late for your answer but try using:
seaborn.set()

Related

How to avoid matplotlib to simplify my Y axis in figure?

the image of what I mean in my question
I'm using BMP280 to measure Temperature and Pressure using Raspberry.
I'm using matplotlib to make a graph, but the matplotlib simplify my Y axis bi adding +9.967e2.
is there any way to avoid matplotlib simplify my Y axis. Sorry I'm new to this so I don't know much.
I tried to search in google but I don't find anything. Maybe I'm using the wrong keyword as I don't know what should I search.
You can turn off the offset as shown in the examples here. For example, if you've made you plot with:
from matplotlib import pyplot as plt
plt.plot(x, y)
then you can turn off the offset with
ax = plt.gca() # get the axes object
# turn off the offset (on the y-axis only)
ax.ticklabel_format(axis="y", useOffset=False)
plt.show()
See the ticklabel_format docs for more info.

Difference between matplotlib.countourf and matlab.contourf() - odd sharp edges in matplotlib

I am a recent migrant from Matlab to Python and have recently worked with Numpy and Matplotlib. I recoded one of my scripts from Matlab, which employs Matlab's contourf-function, into Python using matplotlib's corresponding contourf-function. I managed to replicate the output in Python, apart that the contourf-plots are not exacly the same, for a reason that is unknown to me. As I run the contourf-function in matplotlib, I get this otherwise nice figure but it has these sharp edges on the contour-levels on top and bottom, which should not be there (see Figure 1 below, matplotlib-output). Now, when I export the arrays I used in Python to Matlab (i.e. the exactly same data set that was used to generate the matplotlib-contourf-plot) and use Matlab's contourf-function, I get a slightly different output, without those sharp contour-level edges (see Figure 2 below, Matlab-output). I used the same number of levels in both figures. In figure 3 I have made a scatterplot of the same data, which shows that there are no such sharp edges in the data as shown in the contourf-plot (I added contour-lines just for reference). Example dataset can be downloaded through Dropbox-link given below. The data set contains three txt-files: X, Y, Z. Each of them are an 500x500 arrays, which can be directly used with contourf(), i.e. plt.contourf(X,Y,Z,...). The code that used was
plt.contourf(X,Y,Z,10, cmap=plt.cm.jet)
plt.contour(X,Y,Z,10,colors='black', linewidths=0.5)
plt.axis('equal')
plt.axis('off')
Does anyone have an idea why this happens? I would appreciate any insight on this!
Cheers,
Jussi
Below are the details of my setup:
Python 3.7.0
IPython 6.5.0
matplotlib 2.2.3
Matplotlib output
Matlab output
Matplotlib-scatter
Link to data set
The confusing thing about the matlab plot is that its colorbar shows much more levels than there are actually in the plot. Hence you don't see the actual intervals that are contoured.
You would achieve the same result in matplotlib by choosing 12 instead of 11 levels.
import numpy as np
import matplotlib.pyplot as plt
X, Y, Z = [np.loadtxt("data/roundcontourdata/{}.txt".format(i)) for i in list("XYZ")]
levels = np.linspace(Z.min(), Z.max(), 12)
cntr = plt.contourf(X,Y,Z,levels, cmap=plt.cm.jet)
plt.contour(X,Y,Z,levels,colors='black', linewidths=0.5)
plt.colorbar(cntr)
plt.axis('equal')
plt.axis('off')
plt.show()
So in conclusion, both plots are correct and show the same data. Just the levels being automatically chosen are different. This can be circumvented by choosing custom levels depending on the desired visual appearance.

How do I use colourmaps with variable alpha in a Seaborn kdeplot without seeing the contour lines?

Python version: 3.6.4 (Anaconda on Windows)
Seaborn: 0.8.1
Matplotlib: 2.1.2
I'm trying to create a 2D Kernel Density plot using Seaborn but I want each step in the colourmap to have a different alpha value. I had a look at this question to create a matplotlib colourmap with alpha values: Add alpha to an existing matplotlib colormap.
I have a problem in that the lines between contours are visible. The result I get is here:
I thought that I had found the answer when I found this question: Hide contour linestroke on pyplot.contourf to get only fills. I tried the method outlined in the answer (using set_edgecolor("face") but it did not work in this case. That question also seemed to be related to vector graphics formats and I am just writing out a PNG.
Here is my script:
import numpy as np
import seaborn as sns
import matplotlib.colors as cols
import matplotlib.pyplot as plt
def alpha_cmap(cmap):
my_cmap = cmap(np.arange(cmap.N))
# Set a square root alpha.
x = np.linspace(0, 1, cmap.N)
my_cmap[:,-1] = x ** (0.5)
my_cmap = cols.ListedColormap(my_cmap)
return my_cmap
xs = np.random.uniform(size=100)
ys = np.random.uniform(size=100)
kplot = sns.kdeplot(data=xs, data2=ys,
cmap=alpha_cmap(plt.cm.viridis),
shade=True,
shade_lowest=False,
n_levels=30)
plt.savefig("example_plot.png")
Guided by some comments on this question I have tried some other methods that have been successful when this problem has come up. Based on this question (Matplotlib Contourf Plots Unwanted Outlines when Alpha < 1) I have tried altering the plot call to:
sns.kdeplot(data=xs, data2=ys,
cmap=alpha_cmap(plt.cm.viridis),
shade=True,
shade_lowest=False,
n_levels=30,
antialiased=True)
With antialiased=True the lines between contours are replaced by a narrow white line:
I have also tried an approach similar to this question - Pyplot pcolormesh confused when alpha not 1. This approach is based on looping over the PathCollections in kplot.collections and tuning the parameters of the edges so that they become invisible. I have tried adding this code and tweaking the linewidth -
for thing in kplot.collections:
thing.set_edgecolor("face")
thing.set_linewidth(0.01)
fig.canvas.draw()
This results in a mix of white and dark lines - .
I believe that I will not be able to tune the line width to make the lines disappear because of the variable width of the contour bands.
Using both methods (antialiasing + linewidth) makes this version, which looks cool but isn't quite what I want:
I also found this question - Changing Transparency of/Remove Contour Lines in Matplotlib
This one suggests overplotting a second plot with a different number of contour levels on the same axis, like:
kplot = sns.kdeplot(data=xs, data2=ys,
ax=ax,
cmap=alpha_cmap(plt.cm.viridis),
shade=True,
shade_lowest=False,
n_levels=30,
antialiased=True)
kplot = sns.kdeplot(data=xs, data2=ys,
ax=ax,
cmap=alpha_cmap(plt.cm.viridis),
shade=True,
shade_lowest=False,
n_levels=35,
antialiased=True)
This results in:
This is better, and almost works. The problem here is I need variable (and non-linear) alpha throughout the colourmap. The variable banding and lines seem to be a result of the combinations of alpha when contours are plotted over each other. I also still see some clear/white lines in the result.

Different level of transparency for edgeline and fill in matplotlib or seaborn distribution plot

I would like to set different levels of transparency (= alpha) for the edge line and fill of a distribution plot that I created in matplotlib/seaborn. For example:
ax1 = sns.distplot(BSRDI_DF, label="BsrDI", bins=newBins, kde=False,
hist_kws={"edgecolor": (1,0,0,1), "color":(1,0,0,0.25)})
The above approach does not work, unfortunately. Does anybody have any idea how I could accomplish this?
The problem seems to be that seaborn sets an alpha parameter for the histogram. While alpha defaults to None for a usual histogram, such that something like
plt.hist(x, lw=3, edgecolor=(1,0,0,0.75), color=(1,0,0,0.25))
works as expected, seaborn sets this alpha to some given value. This overwrites the alpha that is set in the RGBA tuples.
The solution is to set alpha explicitely to None:
ax = sns.distplot(x, kde=False, hist_kws={"lw":3, "edgecolor": (1,0,0,0.75),
"color":(1,0,0,0.25),"alpha":None})
A complete example:
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
x = np.random.randn(60)
ax = sns.distplot(x, label="BsrDI", bins=np.linspace(-3,3,10), kde=False,
hist_kws={"lw":3, "edgecolor": (1,0,0,0.75),
"color":(1,0,0,0.25),"alpha":None})
plt.show()
EDIT Nevermind, I thought using color instead of facecolor was causing the problem but it seems the output that I got only looked right because the patches were overlapping, giving seemingly darker edges.
After investigating the issue further, it looks like seaborn is hard-setting the alpha level at 0.4, which supersedes the arguments passed to hist_kws=
sns.distplot(x, kde=False, hist_kws={"edgecolor": (1,0,0,1), "lw":5, "facecolor":(0,1,0,0.1), "rwidth":0.8})
While using the same parameters to plt.hist() gives:
plt.hist(x, edgecolor=(1,0,0,1), lw=5, facecolor=(0,1,0,0.1), rwidth=0.8)
Conclusion: if you want different alpha levels for edges and face colors, you'll have to use matplotlib directly, and not seaborn.

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.