How to make title and legend area in a matplotlib figure not transparent?

Viewed 944

Edit: The issue I have with my example further below I also can recreate with this:

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
plt.ylabel('Y-label');
plt.figtext(0.4, 1.1,'Title:',fontsize=40, color='black',ha ='left',  backgroundcolor='white')
patch_example=mpatches.Patch(color='green', label='label')
plt.legend(fontsize=16, loc='upper center',bbox_to_anchor=(0.5, 1.2), handles=[patch_example])

If you copy and paste the image out of Jupyter Notebook, then the title, legend, and y-label have a transparent background. I want the entire area of the image that's created to have a solid white background. Like it happens with this example from the matplotlib examples:

import matplotlib.pyplot as plt
import numpy as np

# Fixing random state for reproducibility
np.random.seed(19680801)


plt.rcdefaults()
fig, ax = plt.subplots()

# Example data
people = ('Tom', 'Dick', 'Harry', 'Slim', 'Jim')
y_pos = np.arange(len(people))
performance = 3 + 10 * np.random.rand(len(people))
error = np.random.rand(len(people))

ax.barh(y_pos, performance, xerr=error, align='center')
ax.set_yticks(y_pos)
ax.set_yticklabels(people)
ax.invert_yaxis()  # labels read top-to-bottom
ax.set_xlabel('Performance')
ax.set_title('How fast do you want to go today?')

plt.show()

I tried all kinds of different ways, but can't get the area where the title and legend are in not transparent when I copy and paste the image outside of Jupyter Notebook. It seems fine, but as soon as I copy and paste it outside, the area above the main figure stays transparent. I tried all kinds of combinations with facecolor and alpha for the legend, but without success.

What I want to achieve is that the whole thing has a white background when I copy paste it out of Jupyter Notebook.

With the code below the titles have a white background, but only where the text is.

import osmnx as ox
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import matplotlib as mpl
import string
%matplotlib inline  

Address='Kerkstraat, Amersfoort'

# Give each streettype a color based on the name. If both names occur (eg: Rijksstraatweg), first one in the list wins
def colourcode(x):
        # if (your_street in x):
    if x==your_street:
        return '#ff6200'
    elif ('laan' in x): 
        return 'green'
    else:
        return 'gainsboro'
# Give the input street a wider linewidth
def linethick(x):
    if x==your_street: return 7
    else: return 1
   
    # USE THE USER INPUT TO CREATE A GRAPH AROUND THAT ADDRESS
G3 = ox.graph_from_address(Address, network_type='all',dist=200, dist_type='bbox', simplify=False)
edge_attributes = ox.graph_to_gdfs(G3, nodes=False)
    
    # Color every street based on the streettype. First split the address into street and city
your_street=Address.split(',',1)[0].lower()
city=Address.split(',',1)[1].lower().strip()
ec = [colourcode(str(row['name']).lower()) for index, row in edge_attributes.iterrows()]
lw = [linethick(str(row['name']).lower()) for index, row in edge_attributes.iterrows()]
    
#Create figure
fig,ax= ox.plot.plot_graph(G3, bgcolor='white', ax=None, node_size=0, node_color='w', node_edgecolor='gray', node_zorder=2,
                        edge_color=ec, edge_linewidth=lw, edge_alpha=1, figsize=(25,25), dpi=300 , show=False, close=False)
    
# ADD TITLE AND LEGEND: I WANT TO GET A WHITE BACKGROUND FOR THE PART WITH TITLES AND LEGEND 
#Titles
plt.figtext(0.4, 0.94,'Your Street: ' + string.capwords(your_street), fontsize=40, color='#ff6200',ha ='left',  backgroundcolor='white')
plt.figtext(0.4, 0.97, 'Your Place: ' + string.capwords(city), fontsize=40, color='black',ha ='left',  backgroundcolor='white')
    
#Legends
your_street_patch=mpatches.Patch(color='#ff6200', label='Your Street')
lane_patch =mpatches.Patch(color='green', label='Laan')
anders_patch =mpatches.Patch(color='gainsboro', label='Anders')
#create your street legend
first_legend=plt.legend(fontsize=16, frameon=False, bbox_to_anchor=(0.5, 1.07), loc='upper center',handles=[your_street_patch])
# Add the legend manually to the current Axes.
ax = plt.gca().add_artist(first_legend)
# Create another legend for the rest
plt.legend(fontsize=16, frameon=False,loc='upper center',bbox_to_anchor=(0.5, 1.05), ncol=8, handles=[lane_patch,anders_patch])

#show everything
plt.show()

Edit: What I want and what I have as a resulting picture: (https://imgur.com/a/osPQAsp)

Hopefully someone can help me to get it working! Any help is greatly appreciated

1 Answers

Running the small code sample that you have shared reproduces perfectly the issue you are facing. The result is in line with the default matplotlib plotting parameters.

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
plt.ylabel('Y-label')
plt.figtext(0.4, 1.1, 'Title:', fontsize=40, color='black', ha ='left',
            backgroundcolor='white')
patch_example = mpatches.Patch(color='green', label='label')
plt.legend(fontsize=16, loc='upper center', bbox_to_anchor=(0.5, 1.2),
           handles=[patch_example]);

np_background


You can change this by adding the facecolor argument when creating the figure (the remaining black background is not part of the figure png):

fig, ax = plt.subplots(facecolor='white')

plt.ylabel('Y-label')
plt.figtext(0.4, 1.1,'Title:', fontsize=40, color='black', ha ='left',
            backgroundcolor='white')
patch_example = mpatches.Patch(color='green', label='label')
plt.legend(fontsize=16, loc='upper center', bbox_to_anchor=(0.5, 1.2),
           handles=[patch_example]);

white_background


And if the figure is not generated with plt.subplots (e.g. when using another package like pandas or seaborn):

# If you have an Axes object:
ax.figure.set_facecolor('white')

# If you don't:
plt.gcf().set_facecolor('white')
Related