How can I set the background color on specific areas of a pyplot figure? - matplotlib

I've managed to plot a series of points with the following code:
plt = pp.figure()
for i in range(spt.shape[1]):
spktrain = spt[0,i]
for trial in spktrain:
non_z = np.nonzero(trial)
non_z = non_z[0]
pp.plot(t[non_z], trial[non_z], 'bo')
I would like to place alternating bands of white and gray background on the figure in order to separate the data from each iteration of the outer for loop. In other words, I would like the data from each "spktrain" to have it's own background color (the data does not overlap).
How can I go about changing the background color of a figure in a specific region?

You can use axhspan and/or axvspan like this:
import matplotlib.pyplot as plt
plt.figure()
plt.xlim(0, 5)
plt.ylim(0, 5)
for i in range(0, 5):
plt.axhspan(i, i+.2, facecolor='0.2', alpha=0.5)
plt.axvspan(i, i+.5, facecolor='b', alpha=0.5)
plt.show()

Related

matplotlib add artist not showing labels on legend

this is my first question here and one probably very simple, however I tried to fix any mistake and look more info but with no success, I am new to programming graphs using matplotlib, could anyone help me out? thank you in advance
The goal of the program was to graphic a circle and a label, but label was not appearing:
import matplotlib.pyplot as plt
circle1 = plt.Circle((0, 0), 0.2, color='r',label='Men')
fig, ax = plt.subplots()
ax.add_artist(circle1)
circle1 = plt.Circle((0, 0), 2, color='r',label='Men')
plt.legend(loc='best')
plt.show()
Based on your code, you are only plotting the first circle (with radius 0.2). You never call the second circle, so it does not show up. Not sure what you are going for here. However, BigBen is correct, just use ax.add_patch(circle1) instead and it will show with the labels. With this minor change, your plot will look like this:
You would also want to set x and y axis limits in order to see the entire circle. This code below will allow you to see both circles in full with different labels.
import matplotlib.pyplot as plt
circle1 = plt.Circle((0, 0), 0.2, color='r',label='Small Red',zorder=2)
circle2 = plt.Circle((0, 0), 2, color='b',label='Big Blue',zorder=1)
fig, ax = plt.subplots()
ax.add_patch(circle1)
ax.add_patch(circle2)
plt.legend(loc='best')
ax.set_xlim([-3,3])
ax.set_ylim([-3,3])
plt.show()
And your plot will look like this:
The zorder argument will decide which object shows up in front of the other. They will appear front-to-back in descending order.

How can I add an arbitrarily big white margin to a figure with subplots?

I am trying to add an arbitrarily big white margin (or padding) to a figure with subplots because I would like the subtitle of the figure not to overlap with any of the subplots or titles of these subplots. I am using Matplotlib 3.1.2.
Currently, I have the following source code.
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(2, 1, figsize=(15, 10))
n = 10
x = np.arange(0, n)
y = np.random.rand(n)
ax[0].plot(x, y)
ax[0].set_xlabel('x')
ax[0].set_ylabel('y')
y = np.random.rand(n)
ax[1].plot(x, y)
ax[1].set_xlabel('x')
ax[1].set_ylabel('y')
fig.suptitle("I want to have white space around me!!!")
# fig.tight_layout(rect=[0, 0.03, 1, 0.80])
plt.subplots_adjust(top=0.85)
plt.show()
If I try to use either tight_layout or subplots_adjust (as suggested in several answers to this question Matplotlib tight_layout() doesn't take into account figure suptitle), it doesn't seem to have any effect on the margins. Here's the result of the execution of the previous example.
Is there a way to add an arbitrarily big white margin to the left, right, bottom and (or) top of a figure (with subplots)? I would like to specify the figure size and arbitrarily increase or decrease the white space around an image. I also would like the solution to work in case I decide to add a title for each of the subplots. How can this be done?
fig, axs = plt.subplots(2,1, figsize=(5,5))
fig.patch.set_facecolor('grey')
fig.suptitle("Look at all that grey space around me!!!")
fig.subplots_adjust(top=0.6, bottom=0.4, left=0.4, right=0.6)

Matplotlib issue x and y label for multi axes figure

import matplotlib
import matplotlib.pyplot as plt
import numpy as nm
x = nm.linspace(start=0,stop=20,num=30)
fig=plt.figure()
ax1 = fig.add_axes([0,0.6,0.6,0.4])
ax2 = fig.add_axes([0,0,0.8,0.4])
ax1.plot(x,nm.sin(x))
ax1.set_xlabel('x',fontsize=15,color='r')
ax1.set_ylabel('sin(x)',fontsize=15,color='r')
ax2.plot(x,nm.cos(x))
ax2.set_xlabel('x',fontsize=15,color='r')
ax2.set_ylabel('cos(x)',fontsize=15,color='r')
plt.show()
The output I am not able to see the xlabel for ax2 and not able to see both y label for ax1 and ax2..The image is present below:
enter code hereenter image description here
This is expected as you are asking to create an axes that is aligned with the left edge of the figure by using fig.add_axes([0,...]). Same thing for the bottom axes, which you have aligned to the bottom-left of the figure using fig.add_axes([0,0,...]).
Increase the first value e.g. fig.add_axes([0.125,...]) to leave room for the axes decorations on the left or bottom of the axes.
It is generally recommended to use the subplots functions (such as add_subplot, plt.subplots or GridSpec) so that these details are handled automatically.

Overlay two seaborn barplots of different size

Say there are two datasets: a big "background" set, and much smaller "foreground" set. The foreground set comes from the background, but might be much smaller.
I am interested in showing the entire background distribution in an ordered sns.barplot, and have the foreground set a brighter contrasting color to draw attention to these samples.
The best solution I could find is to display one graph on top of the other, but what happens is the graph shrinks down to the smaller domain. Here's what I mean:
import matplotlib.pyplot as plt
import seaborn
# Load the example car crash dataset
crashes = sns.load_dataset("car_crashes").sort_values("total", ascending=False)
# states of interest
txcahi = crashes[crashes['abbrev'].isin(['TX','CA','HI'])]
# Plot the total crashes
f, ax = plt.subplots(figsize=(10, 5))
plt.xticks(rotation=90, fontsize=10)
sns.barplot(y="total", x="abbrev", data=crashes, label="Total", color="lightgray")
# overlay special states onto gray plot as red bars
sns.barplot(y="total", x="abbrev", data=txcahi, label="Total", color="red")
sns.despine(left=True, bottom=True)
This data produces:
But it should look like this (ignore stylistic differences):
Why doesn't this approach work, and what would be a better way to accomplish this?
A seaborn barplot just plots the its n data along the values of 0 to n-1. If instead you'd use a matplotlib bar plot, which is unit aware (from matplotlib 2.2 onwards), it'll work as expected.
import matplotlib.pyplot as plt
import seaborn as sns
# Load the example car crash dataset
crashes = sns.load_dataset("car_crashes").sort_values("total", ascending=False)
# states of interest
txcahi = crashes[crashes['abbrev'].isin(['TX','CA','HI'])]
# Plot the total crashes
f, ax = plt.subplots(figsize=(10, 5))
plt.xticks(rotation=90, fontsize=10)
plt.bar(height="total", x="abbrev", data=crashes, label="Total", color="lightgray")
plt.bar(height="total", x="abbrev", data=txcahi, label="Total", color="red")
sns.despine(left=True, bottom=True)

White background when setting the plot background

The following creates a plot with a white background thereby ignoring set_facecolor.
import matplotlib.pyplot as plt
from descartes.patch import PolygonPatch
import cartopy.crs as ccrs
fig = plt.figure()
ax = fig.add_subplot(111, projection=ccrs.Mercator())
ax.set_facecolor((198/255, 236/255, 253/255))
plt.show()
If I remove where I set the projection, then the color is as expected. How can I set the background color?
I am plotting my own map using shapely polygons using ax.plot. I wish to set the color of the water by setting the background color since my polygons have holes for representing lakes.
Cartopy's projections create various new properties, including two extra patches, the background and outline patches.
It is likely that the background is the one you want to change, but without further example steps this is not certain. Here is how to set each one:
fig = plt.figure();
ax1 = fig.add_subplot(121, projection=ccrs.Mercator())
ax2 = fig.add_subplot(122, projection=ccrs.Mercator())
ax1.background_patch.set_facecolor((198/255, 236/255, 253/255))
ax2.outline_patch.set_facecolor((198/255., 236/255., 253/255.))
plt.show()
Also take care with your color commands -- the example you gave used integer divide, which results in (0,0,0) = black. On the 2nd suplot you see the color you presumably wanted.
For completeness, note that the regular axis patch is turned off, so changes to that patch will not be seen.