2

I'm trying to create a FacetGrid with full and dashed lines like in this comment. Based on the code in the comment and on the FacetGrid doc this should work, however, I only get full lines, no dashes.

Could someone please help me out?

Min. working example:

import matplotlib
import pandas as pd
import seaborn as sns

# toy data
x = [i for i in range(10)]*3
y = [0.5*i for i in range(10)]
y.extend([0.7*i for i in range(10)])
y.extend([0.3*i for i in range(10)])
mode = ["A" for i in range(10)]
mode.extend(["B" for i in range(10)])
mode.extend(["C" for i in range(10)])
method = ["X" for i in range(5)]
method.extend(["Y" for i in range(5)])
method = method*3
df = pd.DataFrame({'x' : x, 'y' : y, 'mode' : mode, 'method' : method})

sns.set_context("paper")
sns.set(style="whitegrid")
blue = matplotlib.colors.hex2color('#5862f4')
pink = matplotlib.colors.hex2color('#e059c3')


kw = {'color': [pink, pink, blue], 'linestyle' : ["-","--","-"]}
p = sns.FacetGrid(df, col='method', hue='mode', sharey='row', margin_titles=True, hue_kws=kw)
p.map(sns.lineplot, 'x', 'y')
p.axes[0,0].set_xlim(0,10)
p.add_legend()

plt.savefig("test.png", bbox_inches='tight')

Result

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
hsvar
  • 177
  • 4
  • 14

1 Answers1

7

Seaborn lineplot overwrites the linestyle such as to use it with its style parameter. Here it seems you do not want to use the style. But also, there seems no reason to use lineplot at all. Hence a normal plt.plot() will work just fine.

kw = {'color': [pink, pink, blue], 'linestyle' : ["-","--","-"]}
g = sns.FacetGrid(df, col='method', hue='mode', sharey='row', margin_titles=True, hue_kws=kw)
g.map(plt.plot, 'x', 'y')

enter image description here

For completeness, here is how one would use the style argument for lineplot with a FacetGrid.

g = sns.FacetGrid(df, col='method', sharey='row', margin_titles=True)
g.map_dataframe(sns.lineplot, 'x', 'y', style="mode", style_order=list("ABC"))

enter image description here

Note that in order to guarantee the consistent mapping of the items of the "mode" column to styles, the style order needs to be set.

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
  • Thank you so much! I think your second version fits better but I would need to assign different colors to the lines and would like control over which mode has which line style and color. Is that possible? – hsvar Jan 06 '19 at 13:09
  • The answer to the question is the first part. What exactly would be the reason not to use the proposed solution here? The second part is only to show the principle. I might remove that second part if it's too confusing. – ImportanceOfBeingErnest Jan 06 '19 at 17:26
  • The problem is that I have several data points per mode for each (x,y) coordinate due to multiple observations. plt.plot() simply draws one line for each observation, whereas sns.lineplot() draws a confidence interval (see first example [here](https://seaborn.pydata.org/generated/seaborn.lineplot.html?highlight=lineplot#seaborn.lineplot)). I'd like the confidence interval, so I'll need to use sns.lineplot. – hsvar Jan 07 '19 at 10:12
  • Okay, I found a working solution. Perhaps you could add it to your answer and then I'll accept it: – hsvar Jan 07 '19 at 10:28
  • You need to set the `hue`, `dashes` and `palette` as well to take control over colors and styles, like so: `p.map_dataframe(sns.lineplot, 'x', 'y', style="mode", hue="mode", style_order=["A", "B", "C"], dashes=["",(2,2),""], palette={"A":pink, "B":pink, "C":blue})` – hsvar Jan 07 '19 at 10:34
  • 1
    I rejected the edit, because I am currently not sure if `dashes` would mind the style order given. Also, there is no `hue_order` defined. If you verified that it does work for all cases (it would require to use a scrambled dataframe), you can provide your own answer. – ImportanceOfBeingErnest Jan 07 '19 at 13:18
  • What do you mean by "If you verified that it does work for all cases (it would require to use a scrambled dataframe)"? According to the doc, dashes works on the style variable, so I'd assume setting style_order should apply to the order of dashes, i.e. if the order is ABC, and the dashes are ["", (2,2), ""] then A and C have solid lines (which is the behaviour I have observed on my real data). – hsvar Jan 07 '19 at 14:36