Kadaj13
Kadaj13

Reputation: 1551

change the factorplot of seaborn to include dots

I have a pandas dataframe that looks like this:

      feat  roi       sbj         alpha test_type       acc
0     cnn2  LOC  Subject1  normal_space   imagery  0.260961
1     cnn2  LOC  Subject1           0.4   imagery  0.755594
2     cnn4  LOC  Subject1  normal_space   imagery  0.282238
3     cnn4  LOC  Subject1           0.4   imagery  0.726485
4     cnn6  LOC  Subject1  normal_space   imagery  0.087359
5     cnn6  LOC  Subject1           0.4   imagery  0.701167
6     cnn8  LOC  Subject1  normal_space   imagery  0.209444
7     cnn8  LOC  Subject1           0.4   imagery  0.612597
8    glove  LOC  Subject1  normal_space   imagery  0.263176
9    glove  LOC  Subject1           0.4   imagery  0.659182
10    cnn2  FFA  Subject1  normal_space   imagery  0.276830
11    cnn2  FFA  Subject1           0.4   imagery  0.761014
12    cnn4  FFA  Subject1  normal_space   imagery  0.288127
13    cnn4  FFA  Subject1           0.4   imagery  0.727325
14    cnn6  FFA  Subject1  normal_space   imagery  0.113507
15    cnn6  FFA  Subject1           0.4   imagery  0.732963
16    cnn8  FFA  Subject1  normal_space   imagery  0.264455
17    cnn8  FFA  Subject1           0.4   imagery  0.615467
18   glove  FFA  Subject1  normal_space   imagery  0.245950
19   glove  FFA  Subject1           0.4   imagery  0.640502
20    cnn2  PPA  Subject1  normal_space   imagery  0.344078
...

For plotting it, I wrote:

ax = sns.factorplot(x="feat", y="acc", col="roi", hue="alpha", alpha = 0.9, data=df_s_pt, kind="bar").set(title = "perception, scene wise correlation")

The result look like this:

enter image description here

I want to upgrade it so it can look like the one in this answer (so it has the dots of each subject (i.e., Subject1, Subject2, ...))

Also, I want to control the color.

I could'nt use the code in that answer. How should I apply having dots/color change in factorplot?

Upvotes: 0

Views: 437

Answers (1)

JohanC
JohanC

Reputation: 80449

Some remarks:

  • sns.factorplot is a very old function. In the newer seaborn versions it has been replaced by sns.catplot. To take advantage of the hard work in correcting, improving and extending the library, it is highly recommended to upgrade to the latest version (0.12.2)
  • Functions that create multiple subplots in one go, don't return an ax, but a grid of subplots (a FacetGrid). It is extremely confusing storing the result of such a function in ax, as matplotlib's axes functions won't work on them.
  • Calling set(title=...) on the FacetGrid changes the titles of the individual subplots. It therefore removes the title given by seaborn to indicate the feature used for each subplot ('roi' in the current example).
  • To change the overall title, g.fig.suptitle(...) can be used. Some extra space needs to be provided, as that doesn't happen automatically.
  • The latest seaborn versions have a function g.map_dataframe to apply a function to each subset used corresponding to its subplot.
  • Colors can be controlled via the palette= parameter. Either individual colors, or a colormap can be chosen.
  • To make sure the order is the same everywhere, it often helps to make the dataframe columns of type pd.Categorical.
  • You might want to suppress the errorbars with sns.catplot(..., errorbar=None)

Here is an example starting from dummy test data.

from matplotlib import pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np

df = pd.DataFrame({'feat': np.random.choice(['cnn2', 'cnn4', 'cnn6', 'cnn8', 'glove'], 100),
                   'roi': np.random.choice(['LOC', 'FFA'], 100),
                   'alpha': np.random.choice(['normal_space', 0.4], 100),
                   'acc': 1 - np.random.rand(100) ** 2})
df['feat'] = pd.Categorical(df['feat'])
df['roi'] = pd.Categorical(df['roi'])
df['alpha'] = pd.Categorical(df['alpha'])

g = sns.catplot(x="feat", y="acc", col="roi", hue="alpha", palette=['crimson', 'limegreen'],
                alpha=0.9, data=df, kind="bar")
g.map_dataframe(sns.stripplot, x="feat", y="acc", hue="alpha", palette=['cornflowerblue', 'yellow'],
                edgecolor="black", linewidth=.75, dodge=True)
g.set(xlabel='')  # remove the xlabels if they are already clear from the xticks
g.fig.subplots_adjust(top=0.9)  # need extra space for the overall title
g.fig.suptitle("perception, scene wise correlation")
plt.show()

combining facetgrid of barplot with stripplot

Upvotes: 1

Related Questions