Change color of seaborn lineplot - python

I have a seaborn lineplot:
plt.figure(figsize=(22,14))
sns.lineplot(x="Datum", y="Value", ci=None, hue='Type', data=df)
plt.show()
Which leads to the following output:
How can i change the linecolors? For me the difference is hard to see.

You can change colors using palettes. Referring to https://seaborn.pydata.org/tutorial/color_palettes.html, try:
import seaborn as sns; sns.set()
import matplotlib.pyplot as plt
fmri = sns.load_dataset("fmri")
# Try playing with one set or another:
#sns.set_palette("husl")
sns.set_palette("PuBuGn_d")
ax = sns.lineplot(x="timepoint", y="signal", hue="event", data=fmri)
you'll get different line colors, like this
or this

You can use colour inside lineplot() method, however this, far as I know, works only with Series.
You can transform your data to Series with this this:
data = pd.Series(another_data)
Then plot Your data
sns.lineplot(..., data=data, color='red')
Another way is to use pallets
palette = sns.color_palette("mako_r", 6)
sns.lineplot(..., palette=palette, data=data)
More you can find in Seaborn lineplot reference: https://seaborn.pydata.org/generated/seaborn.lineplot.html
Or here:
https://stackoverflow.com/a/58432483/12366487

At least in version 0.11.2 of seaborn, the lineplot function (http://seaborn.pydata.org/generated/seaborn.lineplot.html) has a parameter called palette that allows changing the color map used for the hue.
To check the available color maps you can refer to https://matplotlib.org/stable/tutorials/colors/colormaps.html
import seaborn as sns
import matplotlib.pyplot as plt
fmri = sns.load_dataset("fmri")
#sns.lineplot(x="timepoint", y="signal", hue="event", data=fmri, palette="tab10")
sns.lineplot(x="timepoint", y="signal", hue="event", data=fmri, palette="Accent")

Related

How to increase the figure size of a Seaborn Plot? [duplicate]

How do I change the size of my image so it's suitable for printing?
For example, I'd like to use to A4 paper, whose dimensions are 11.7 inches by 8.27 inches in landscape orientation.
You can also set figure size by passing dictionary to rc parameter with key 'figure.figsize' in seaborn set method:
import seaborn as sns
sns.set(rc={'figure.figsize':(11.7,8.27)})
Other alternative may be to use figure.figsize of rcParams to set figure size as below:
from matplotlib import rcParams
# figure size in inches
rcParams['figure.figsize'] = 11.7,8.27
More details can be found in matplotlib documentation
You need to create the matplotlib Figure and Axes objects ahead of time, specifying how big the figure is:
from matplotlib import pyplot
import seaborn
import mylib
a4_dims = (11.7, 8.27)
df = mylib.load_data()
fig, ax = pyplot.subplots(figsize=a4_dims)
seaborn.violinplot(ax=ax, data=df, **violin_options)
Note that if you are trying to pass to a "figure level" method in seaborn (for example lmplot, catplot / factorplot, jointplot) you can and should specify this within the arguments using height and aspect.
sns.catplot(data=df, x='xvar', y='yvar',
hue='hue_bar', height=8.27, aspect=11.7/8.27)
See https://github.com/mwaskom/seaborn/issues/488 and Plotting with seaborn using the matplotlib object-oriented interface for more details on the fact that figure level methods do not obey axes specifications.
first import matplotlib and use it to set the size of the figure
from matplotlib import pyplot as plt
import seaborn as sns
plt.figure(figsize=(15,8))
ax = sns.barplot(x="Word", y="Frequency", data=boxdata)
You can set the context to be poster or manually set fig_size.
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
np.random.seed(0)
n, p = 40, 8
d = np.random.normal(0, 2, (n, p))
d += np.log(np.arange(1, p + 1)) * -5 + 10
# plot
sns.set_style('ticks')
fig, ax = plt.subplots()
# the size of A4 paper
fig.set_size_inches(11.7, 8.27)
sns.violinplot(data=d, inner="points", ax=ax)
sns.despine()
fig.savefig('example.png')
This can be done using:
plt.figure(figsize=(15,8))
sns.kdeplot(data,shade=True)
In addition to elz answer regarding "figure level" methods that return multi-plot grid objects it is possible to set the figure height and width explicitly (that is without using aspect ratio) using the following approach:
import seaborn as sns
g = sns.catplot(data=df, x='xvar', y='yvar', hue='hue_bar')
g.fig.set_figwidth(8.27)
g.fig.set_figheight(11.7)
This shall also work.
from matplotlib import pyplot as plt
import seaborn as sns
plt.figure(figsize=(15,16))
sns.countplot(data=yourdata, ...)
For my plot (a sns factorplot) the proposed answer didn't works fine.
Thus I use
plt.gcf().set_size_inches(11.7, 8.27)
Just after the plot with seaborn (so no need to pass an ax to seaborn or to change the rc settings).
See How to change the image size for seaborn.objects for a solution with the new seaborn.objects interface from seaborn v0.12, which is not the same as seaborn axes-level or figure-level plots.
Adjusting the size of the plot depends if the plot is a figure-level plot like seaborn.displot, or an axes-level plot like seaborn.histplot. This answer applies to any figure or axes level plots.
See the the seaborn API reference
seaborn is a high-level API for matplotlib, so seaborn works with matplotlib methods
Tested in python 3.8.12, matplotlib 3.4.3, seaborn 0.11.2
Imports and Data
import seaborn as sns
import matplotlib.pyplot as plt
# load data
df = sns.load_dataset('penguins')
sns.displot
The size of a figure-level plot can be adjusted with the height and/or aspect parameters
Additionally, the dpi of the figure can be set by accessing the fig object and using .set_dpi()
p = sns.displot(data=df, x='flipper_length_mm', stat='density', height=4, aspect=1.5)
p.fig.set_dpi(100)
Without p.fig.set_dpi(100)
With p.fig.set_dpi(100)
sns.histplot
The size of an axes-level plot can be adjusted with figsize and/or dpi
# create figure and axes
fig, ax = plt.subplots(figsize=(6, 5), dpi=100)
# plot to the existing fig, by using ax=ax
p = sns.histplot(data=df, x='flipper_length_mm', stat='density', ax=ax)
Without dpi=100
With dpi=100
# Sets the figure size temporarily but has to be set again the next plot
plt.figure(figsize=(18,18))
sns.barplot(x=housing.ocean_proximity, y=housing.median_house_value)
plt.show()
Some tried out ways:
import seaborn as sns
import matplotlib.pyplot as plt
ax, fig = plt.subplots(figsize=[15,7])
sns.boxplot(x="feature1", y="feature2",data=df) # where df would be your dataframe
or
import seaborn as sns
import matplotlib.pyplot as plt
plt.figure(figsize=[15,7])
sns.boxplot(x="feature1", y="feature2",data=df) # where df would be your dataframe
The top answers by Paul H and J. Li do not work for all types of seaborn figures. For the FacetGrid type (for instance sns.lmplot()), use the size and aspect parameter.
Size changes both the height and width, maintaining the aspect ratio.
Aspect only changes the width, keeping the height constant.
You can always get your desired size by playing with these two parameters.
Credit: https://stackoverflow.com/a/28765059/3901029

Seaborn FacetGrid maximize size [duplicate]

How do I change the size of my image so it's suitable for printing?
For example, I'd like to use to A4 paper, whose dimensions are 11.7 inches by 8.27 inches in landscape orientation.
You can also set figure size by passing dictionary to rc parameter with key 'figure.figsize' in seaborn set method:
import seaborn as sns
sns.set(rc={'figure.figsize':(11.7,8.27)})
Other alternative may be to use figure.figsize of rcParams to set figure size as below:
from matplotlib import rcParams
# figure size in inches
rcParams['figure.figsize'] = 11.7,8.27
More details can be found in matplotlib documentation
You need to create the matplotlib Figure and Axes objects ahead of time, specifying how big the figure is:
from matplotlib import pyplot
import seaborn
import mylib
a4_dims = (11.7, 8.27)
df = mylib.load_data()
fig, ax = pyplot.subplots(figsize=a4_dims)
seaborn.violinplot(ax=ax, data=df, **violin_options)
Note that if you are trying to pass to a "figure level" method in seaborn (for example lmplot, catplot / factorplot, jointplot) you can and should specify this within the arguments using height and aspect.
sns.catplot(data=df, x='xvar', y='yvar',
hue='hue_bar', height=8.27, aspect=11.7/8.27)
See https://github.com/mwaskom/seaborn/issues/488 and Plotting with seaborn using the matplotlib object-oriented interface for more details on the fact that figure level methods do not obey axes specifications.
first import matplotlib and use it to set the size of the figure
from matplotlib import pyplot as plt
import seaborn as sns
plt.figure(figsize=(15,8))
ax = sns.barplot(x="Word", y="Frequency", data=boxdata)
You can set the context to be poster or manually set fig_size.
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
np.random.seed(0)
n, p = 40, 8
d = np.random.normal(0, 2, (n, p))
d += np.log(np.arange(1, p + 1)) * -5 + 10
# plot
sns.set_style('ticks')
fig, ax = plt.subplots()
# the size of A4 paper
fig.set_size_inches(11.7, 8.27)
sns.violinplot(data=d, inner="points", ax=ax)
sns.despine()
fig.savefig('example.png')
This can be done using:
plt.figure(figsize=(15,8))
sns.kdeplot(data,shade=True)
In addition to elz answer regarding "figure level" methods that return multi-plot grid objects it is possible to set the figure height and width explicitly (that is without using aspect ratio) using the following approach:
import seaborn as sns
g = sns.catplot(data=df, x='xvar', y='yvar', hue='hue_bar')
g.fig.set_figwidth(8.27)
g.fig.set_figheight(11.7)
This shall also work.
from matplotlib import pyplot as plt
import seaborn as sns
plt.figure(figsize=(15,16))
sns.countplot(data=yourdata, ...)
For my plot (a sns factorplot) the proposed answer didn't works fine.
Thus I use
plt.gcf().set_size_inches(11.7, 8.27)
Just after the plot with seaborn (so no need to pass an ax to seaborn or to change the rc settings).
See How to change the image size for seaborn.objects for a solution with the new seaborn.objects interface from seaborn v0.12, which is not the same as seaborn axes-level or figure-level plots.
Adjusting the size of the plot depends if the plot is a figure-level plot like seaborn.displot, or an axes-level plot like seaborn.histplot. This answer applies to any figure or axes level plots.
See the the seaborn API reference
seaborn is a high-level API for matplotlib, so seaborn works with matplotlib methods
Tested in python 3.8.12, matplotlib 3.4.3, seaborn 0.11.2
Imports and Data
import seaborn as sns
import matplotlib.pyplot as plt
# load data
df = sns.load_dataset('penguins')
sns.displot
The size of a figure-level plot can be adjusted with the height and/or aspect parameters
Additionally, the dpi of the figure can be set by accessing the fig object and using .set_dpi()
p = sns.displot(data=df, x='flipper_length_mm', stat='density', height=4, aspect=1.5)
p.fig.set_dpi(100)
Without p.fig.set_dpi(100)
With p.fig.set_dpi(100)
sns.histplot
The size of an axes-level plot can be adjusted with figsize and/or dpi
# create figure and axes
fig, ax = plt.subplots(figsize=(6, 5), dpi=100)
# plot to the existing fig, by using ax=ax
p = sns.histplot(data=df, x='flipper_length_mm', stat='density', ax=ax)
Without dpi=100
With dpi=100
# Sets the figure size temporarily but has to be set again the next plot
plt.figure(figsize=(18,18))
sns.barplot(x=housing.ocean_proximity, y=housing.median_house_value)
plt.show()
Some tried out ways:
import seaborn as sns
import matplotlib.pyplot as plt
ax, fig = plt.subplots(figsize=[15,7])
sns.boxplot(x="feature1", y="feature2",data=df) # where df would be your dataframe
or
import seaborn as sns
import matplotlib.pyplot as plt
plt.figure(figsize=[15,7])
sns.boxplot(x="feature1", y="feature2",data=df) # where df would be your dataframe
The top answers by Paul H and J. Li do not work for all types of seaborn figures. For the FacetGrid type (for instance sns.lmplot()), use the size and aspect parameter.
Size changes both the height and width, maintaining the aspect ratio.
Aspect only changes the width, keeping the height constant.
You can always get your desired size by playing with these two parameters.
Credit: https://stackoverflow.com/a/28765059/3901029

Create an artificial legend in seaborn

I want to add an artificial legend to my plot. It is artificial because I didn't group my observation (see code below).It means I can't solve this problem with plt.legend() function: it requires grouped variables. Is there any way to handle it?
My code:
sns.set(rc={'figure.figsize':(11.7,8.27)})
sns.set_theme(style="white")
ax = sns.boxplot(data = data.values.tolist(),palette=['white', 'black'])
ax.set_xticklabels(labels, fontsize=14)
ax.tick_params(labelsize=14)
and plot looks like:
My desire is to add a legend (maybe it is not a legend at all just a drawing) where will be written something like (sorry for size):
You can create a legend from the artists created by Seaborn as follows:
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
sns.set_theme(style="white")
ax = sns.boxplot(data = np.random.randn(20,20), palette=['white', 'black'])
handles = ax.artists[:2]
handles[0].set_label("First")
handles[1].set_label("Second")
ax.legend(handles=handles)
plt.show()
As I do not have your data, I can not replicate your charts. However, you might try adding the following line at the end (after importing matplotlib.pyplot as plt).
plt.legend(['First','Second'])

How can I have markers in Time Series Plot with Python Seaborn

I have the following reference plot from Seaborn
import seaborn as sns;
sns.set()
import matplotlib.pyplot as plt
fmri = sns.load_dataset("fmri")
ax = sns.lineplot(x="timepoint", y="signal", hue="event", style="event", markers=True, data=fmri)
The above code results in the following plot:
However, when I replace the last line of the above code with this:
ax = sns.lineplot(x="timepoint", y="signal", markers=True, data=fmri)
I get the following plot:
My Question is:
How can I incorporate markers in the single plot above? It appears that the markers = True do not work here. Is there any way to get around with this?

Rotate label text in seaborn factorplot

I have a simple factorplot
import seaborn as sns
g = sns.factorplot("name", "miss_ratio", "policy", dodge=.2,
linestyles=["none", "none", "none", "none"], data=df[df["level"] == 2])
The problem is that the x labels all run together, making them unreadable. How do you rotate the text so that the labels are readable?
I had a problem with the answer by #mwaskorn, namely that
g.set_xticklabels(rotation=30)
fails, because this also requires the labels. A bit easier than the answer by #Aman is to just add
plt.xticks(rotation=45)
You can rotate tick labels with the tick_params method on matplotlib Axes objects. To provide a specific example:
ax.tick_params(axis='x', rotation=90)
This is still a matplotlib object. Try this:
# <your code here>
locs, labels = plt.xticks()
plt.setp(labels, rotation=45)
Any seaborn plots suported by facetgrid won't work with (e.g. catplot)
g.set_xticklabels(rotation=30)
however barplot, countplot, etc. will work as they are not supported by facetgrid. Below will work for them.
g.set_xticklabels(g.get_xticklabels(), rotation=30)
Also, in case you have 2 graphs overlayed on top of each other, try set_xticklabels on graph which supports it.
If anyone wonders how to this for clustermap CorrGrids (part of a given seaborn example):
import seaborn as sns
import matplotlib.pyplot as plt
sns.set(context="paper", font="monospace")
# Load the datset of correlations between cortical brain networks
df = sns.load_dataset("brain_networks", header=[0, 1, 2], index_col=0)
corrmat = df.corr()
# Set up the matplotlib figure
f, ax = plt.subplots(figsize=(12, 9))
# Draw the heatmap using seaborn
g=sns.clustermap(corrmat, vmax=.8, square=True)
rotation = 90
for i, ax in enumerate(g.fig.axes): ## getting all axes of the fig object
ax.set_xticklabels(ax.get_xticklabels(), rotation = rotation)
g.fig.show()
You can also use plt.setp as follows:
import matplotlib.pyplot as plt
import seaborn as sns
plot=sns.barplot(data=df, x=" ", y=" ")
plt.setp(plot.get_xticklabels(), rotation=90)
to rotate the labels 90 degrees.
For a seaborn.heatmap, you can rotate these using (based on #Aman's answer)
pandas_frame = pd.DataFrame(data, index=names, columns=names)
heatmap = seaborn.heatmap(pandas_frame)
loc, labels = plt.xticks()
heatmap.set_xticklabels(labels, rotation=45)
heatmap.set_yticklabels(labels[::-1], rotation=45) # reversed order for y
One can do this with matplotlib.pyplot.xticks
import matplotlib.pyplot as plt
plt.xticks(rotation = 'vertical')
# Or use degrees explicitly
degrees = 70 # Adjust according to one's preferences/needs
plt.xticks(rotation=degrees)
Here one can see an example of how it works.
Use ax.tick_params(labelrotation=45). You can apply this to the axes figure from the plot without having to provide labels. This is an alternative to using the FacetGrid if that's not the path you want to take.
If the labels have long names it may be hard to get it right. A solution that worked well for me using catplot was:
import matplotlib.pyplot as plt
fig = plt.gcf()
fig.autofmt_xdate()

Categories