0

I want to have control over the face color of (sub)plots when I use matplotlib.

For example, if I run,

tips = sns.load_dataset("tips")
f, ax = plt.subplots(subplot_kw=dict(facecolor=".9"))
sns.scatterplot(data=tips, x="total_bill", y="tip")

I get this,

enter image description here

where the default white face color is changed to gray. Running though,

tips = sns.load_dataset("tips")
rows, cols = 1, 1
f, axs = plt.subplots( rows, cols, subplot_kw=dict(facecolor=".9"))
plt.subplot( rows, cols, 1)
sns.scatterplot(data=tips, x="total_bill", y="tip")

gives,

enter image description here

Setting explicitly the face color at each subplot command resolves it, i.e.,

tips = sns.load_dataset("tips")
rows, cols = 1, 1
f, axs = plt.subplots( rows, cols)
plt.subplot( rows, cols, 1, facecolor=".9")
sns.scatterplot(data=tips, x="total_bill", y="tip")

enter image description here

However, when I use plt.box( False) or

ax = plt.subplot( rows, cols, 1, facecolor = ".9")
ax.set_frame_on( False)

or

plt.subplot( rows, cols, 1, facecolor = ".9", frame_on = False)

the problem returns. It appears that, custom face color with no frame cannot be met as "configurations".

From the documentation of frame_on property, "Set whether the axes rectangle patch is drawn.", https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.set_frame_on.html#matplotlib.axes.Axes.set_frame_on. Hence, it looks like that matplotlib adds a patch to change the face color.

Is it then possible to change the edge color of this patch? I don't want to have this "thick" border line of the frame. Is adding my own patch the only alternative?

EDIT

When I try this,

tips = sns.load_dataset("tips")
rows, cols = 2, 1
f, axs = plt.subplots( rows, cols, figsize = ( 10, 10), subplot_kw = dict( facecolor = ".9"))
plt.subplot( rows, cols, 1)
sns.scatterplot(data=tips, x="total_bill", y="tip", ax = axs[ 0])
axs[ 0].grid( color = 'w', linewidth = 1)
[ axs[ 0].spines[ s].set_visible( False) for s in axs[ 0].spines.keys()]

I get this,

enter image description here

The problem is that I am calling plt.subplot() that creates a new axis overriding the one at location ( rows, cols, 1). Deleting this line solves the problem.

Thanks.

vpap
  • 1,389
  • 2
  • 21
  • 32
  • also, seeing this in the current answer as well, fyi, when you call `ax = plt.subplot( rows, cols)` after `f, axs = plt.subplots( rows, cols, subplot_kw=dict(facecolor=".9"))` you are not accessing your axis, you are creating a new axis and laying it on top of your grey colored one, that's why you get a plot with a white face color. – dm2 Jul 05 '20 at 21:15
  • @dm2 how could I avoid this especially when I have many subplots? Thanks. – vpap Jul 05 '20 at 21:27
  • 1
    you just need to use the axes your have already created in `fig, axs = plt.subplots()` assignement. If you check axs object here is an array of matplotlib axes, so to plot on them you need to access individual axis, either looping through them or indexing the array. In your current case (1 row, 1 column subplot), axes is equal to a single ax object, so no access is needed (just plot). Otherwise, in seaborn you can specifically pass an 'ax' parameter, so to access a specific axis you could do `sns.scatterplot(ax = axs[0])`. This way, you wouldn't need to set face_color for each axis. – dm2 Jul 05 '20 at 21:34

1 Answers1

3

You can use set_visible method of spines

tips = sns.load_dataset("tips")
rows, cols = 1, 1
f, axs = plt.subplots( rows, cols)
ax = plt.subplot( rows, cols, 1, facecolor=".9")
for s in ax.spines:
  ax.spines[s].set_visible(False)

sns.scatterplot(data=tips, x="total_bill", y="tip")

enter image description here

mujjiga
  • 16,186
  • 2
  • 33
  • 51
  • It works, thanks. I did it like this `[ ax.spines[ s].set_visible( False) for s in ax.spines.keys()]`. – vpap Jul 05 '20 at 21:33