5

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://i.stack.imgur.com/8ybkP.jpg)

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

Sanne Hombroek
  • 105
  • 1
  • 6
  • 1
    I am not sure of the state you are tasked with. Can you provide a picture of the current graph? Also, can you provide data that the respondent can reproduce? – r-beginners Feb 08 '21 at 02:09
  • It is hard to answer your question seeing as you have not provided a [_small reproducible_ example](https://stackoverflow.com/help/minimal-reproducible-example) that we can easily copy-paste to test. If you are not used to creating small reproducible plots, I invite you to copy one from the [matplotlib gallery](https://matplotlib.org/gallery/index.html) which reproduces the problem you are facing. And posting a couple of images (problem and expected result) would be a plus. Maybe all you need is `fig.set_facecolor('white')`. – Patrick FitzGerald Feb 08 '21 at 17:00
  • thanks for the feedback, I will try to reproduce the issue with a smaller set where there are no additional packages needed. I already made it smaller than my entire script, but didn't think about the osmnx packages that is necessary to run this script. (with that package installed, this script should run) – Sanne Hombroek Feb 08 '21 at 18:55
  • I added pictures of what I want and what I have. I tried to create a small reproducible example based on the matplotlib examples, but then I'm not able to recreate my issue. With the OSMNX package installed my code should run with copy paste.. – Sanne Hombroek Feb 08 '21 at 22:21
  • Now I also added a very basic example that has the same issue. Hopefully if someone solves it for that, I can reuse that solution for my actual case.. The end-result of what I'm doing can be found here: https://sannehombroek.github.io/nbinteract-tutorial/streetcolors4.html – Sanne Hombroek Feb 08 '21 at 23:08
  • Did you try changing the `facecolor` as I suggested in my last comment? In any case, thank you for having taken the time to provide a small copy-pastable code sample and the images. Also, note that in order for commenters to be notified of your responses, [you must include '@username'](https://meta.stackexchange.com/questions/19756/how-do-comments-work) (hence my late response). As you can notice, I do not need to add this seeing as I am commenting under your question. – Patrick FitzGerald Feb 13 '21 at 11:21
  • Thanks again @PatrickFitzGerald. That did solve it indeed for the small example, I still have to try it for my original problem. (probably with ax.figure.set_facecolor('white') since I'm not sure what the Osmnx plot_graph is using, but adding the facecolor there directly didn't work). – Sanne Hombroek Feb 14 '21 at 17:28

1 Answers1

6

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')
Patrick FitzGerald
  • 3,280
  • 2
  • 18
  • 30