Change default background color for matplotlib plots - matplotlib

I am using ipython with matplotlib. Is it possible to configure the default background color for matplotlib plots? The curent (white) colour must come from somewhere. Is it possible to override it to, lets say, #CCCCCC?
Note: By default, I don't mean default for a given ipython notebook. I mean default for my matplotlib installation.
The solution suggested by #Ffisegydd works. however, after setting axes.facecolor : F4EAEA, I still get white edges around the plot:
How can I get rid of those?
UPDATE:
now I have following set in my /etc/matplotlibrc and I have restarted ipython notebook after each change;
axes.facecolor : F4EAEA
figure.facecolor : F4EAEA
figure.edgecolor : F4EAEA
savefig.facecolor : F4EAEA
savefig.edgecolor : F4EAEA
The plot looks the same as on the original screenshot. i.e. there is the white stripe around the plot.
UPDATE2:
I am using ipython, and I have following custom css in my ~/.config/ipython/profile_nbserver/static/custom/custom.css
div.output_area {
border-radius: 4px;
background: #F4EAEA !important;
border: thin solid #4a4a4a;
}

You need to set both the axes and figure background colors:
f = plt.figure(facecolor=".6")
ax = f.add_subplot(111, axisbg=".6")
ax.plot([0, 1, 2], [1, 0, 2])
There is additionally a distinction between the facecolor for the interactive plot and what gets saved; you also have to pass facecolor to f.savefig if you want a uniform background on the resulting file.
You can change the defaults with the following fields in the rcParams dictionary:
import matplotlib as mpl
mpl.rcParams["figure.facecolor"]
mpl.rcParams["axes.facecolor"]
mpl.rcParams["savefig.facecolor"]
Note that this works a little unexpectedly in the IPython notebook with an inline backend, where the "saved" version of the figure you see below the cell is not controlled by the figure parameter, but by the savefig paramter.

You can customise matplotlib in a variety of ways.
If you're looking to customise across your entire computer then matplotlib uses the "matplotlibrc" configuration file as a default.
If you wish to edit this to change the default axes facecolor (the technical term for the background) then you'll need to uncomment and adjust this line:
#axes.facecolor : white # axes background color
If you wish to set your background colour to #CCCCCC then you should change the line to:
axes.facecolor : CCCCCC # axes background color
N.B. if you re-install matplotlib this will be overwritten. To prevent this you can save it in "HOME/.matplotlib/matplotlibrc" as the example comments state.
Should you wish to change it to a different colour temporarily then simply add the following at the top of your script:
import matplotlib as mpl
mpl.rcParams['axes.facecolor'] = '111111' # Or any suitable colour...
If you should wish to modify an individual matplotlib.axes object then just use ax.set_axis_bgcolor('...').

Related

GeoViews: Applying matplotlib styling parameters to Polygons elements

Installed packages
holoviews 1.14.4, geoviews 1.9.1., matplotlib 3.4.2.
What I'm trying to do
I am trying to apply simple per-feature styles using GeoViews and the matplolib backend. I cannot figure out how to apply different edgecolor= parameters to different gv.Polygons elements in the same overlay. For some reason, they're always lightblue...
Similarly, facecolor= seems to have no effect.
Reproducible code sample
This uses a very small sample of the full dataset.
import pandas as pd
import geopandas as gpd
import geoviews as gv
from geoviews import opts
# loading both extensions as the full script calls for user input
# to choose between an interactive or static output
gv.extension('bokeh', 'matplotlib')
d1 = {'use': {0: 'Residential', 1: 'Residential'},
'geometry': {0: 'POLYGON ((13.80961103741604 51.04076975651729, 13.80965521888065 51.04079016168103, 13.80963851766593 51.04080454197601, 13.80959433642561 51.04078412781548, 13.80961103741604 51.04076975651729))',
1: 'POLYGON ((13.80977831740752 51.04313480566009, 13.80987122363639 51.04306085051974, 13.8099989591537 51.04312462457182, 13.80995486494384 51.04315973323087, 13.8099651184249 51.04316486464228, 13.80991634926543 51.04320371166482, 13.80977831740752 51.04313480566009))'}}
gdf1 = gpd.GeoDataFrame(pd.DataFrame(d1), geometry=gpd.GeoSeries.from_wkt(pd.DataFrame(d1)['geometry']), crs="EPSG:4326")
d2 = {'geometry': {1: 'POLYGON ((13.80894179055831 51.04544128170094, 13.80952887156242 51.0450399782091, 13.80954152432486 51.04504668985658, 13.80896834397535 51.04545611172818, 13.80894179055831 51.04544128170094))'}}
gdf2 = gpd.GeoDataFrame(pd.DataFrame(d2), geometry=gpd.GeoSeries.from_wkt(pd.DataFrame(d2)['geometry']), crs="EPSG:4326")
layout = gv.Polygons(gdf1, group="group1") * gv.Polygons(gdf2, group="group2")
layout.opts(
opts.Polygons('group1', cmap=['red'], edgecolor='black', linewidth=0.5, xaxis=None, yaxis=None, backend="matplotlib"),
opts.Polygons('group2', cmap=['lightblue'], edgecolor='blue', linewidth=0.5, backend="matplotlib"),
opts.Overlay(fig_size=500, backend='matplotlib')
)
gv.output(layout, backend='matplotlib')
gv.save(layout, "test.svg", dpi=600, backend='matplotlib')
Screenshot of the observed behaviour
This is a screen from the full dataset.
Expected behaviour
The red fill polygons belong to gdf1 and should have a black edgecolor but it's light blue instead. The blue fill polygon belongs to gdf2 and should have a lightblue fill and blue edgecolor, though the same color seems to be applied to both fill and edge.
What I've tried
Instead of using the group= parameter to specify styling for each of the Polygon elements (which I accidentally stumbled upon through the datashader documentation), I tried making multiple opts calls 'in-line' as suggested in the documentation for HoloViews here. This also has no effect.
Also, cmap=['color'] is the only method I've found to work to have GeoViews not use the automatically detected 'use' column in gdf1 as a vdim for color mapping. Is this the canonical approach and/or expected behaviour? color= or facecolor= seems to have no effect even though they are listed when calling gv.help(gv.opts.Polygons).
In short, I don't understand how to apply these particular styling parameters for the matplotlib backend and would very much appreciate any pointers.
2-Aug-21 Edit
Another strange behaviour seems to be that the figure in the, in my case VSCode-Python, interpreter, where the symbology seems to be faithfully represented, looks different from the .svg output generated by gv.save(layout, "test.svg", dpi=600, backend='matlplotlib'). The below images are outputs from the same run of the script.
Interpreter output:
gv.save() output:

Python: Setting Seaborn lineplot error band edge color

I am using Seaborn to make lineplots with a band indicating standard deviations. Something just like the second/third plot in the doc below:
https://seaborn.pydata.org/generated/seaborn.lineplot.html?highlight=lineplot#seaborn.lineplot
I am wondering is that possible to set the edgecolor for the error band separately? I can change linestyle of the band through err_kws. But, if I pass "edgecolor" through err_kws, it seems that nothing happens. Is there someway to allow me to get control with the edges?
Thanks!
As djakubosky notes, the color of the line and the error band are coupled together internally in seaborn's lineplot. I suggest that it is cleaner to modify the properties of the artists after the plot has been generated. This is a cleaner alternative than editing the library source code directly (maintenance headaches, etc).
For the example data shown on the sns.lineplot docs, we can update the error band properties as follows:
import seaborn as sns
fmri = sns.load_dataset("fmri")
ax = sns.lineplot(x="timepoint", y="signal", data=fmri)
# by inspection we see that the PolyCollection is the first artist
for child in ax.get_children():
print(type(child))
# and so we can update its properties
ax.get_children()[0].set_color('k')
ax.get_children()[0].set_hatch('//')
It may be more robust to select by property of the artist rather than selecting the first artist (especially if you have already rendered something on the same axes), e.g. along these lines:
from matplotlib.collections import PolyCollection
for child in ax.findobj(PolyCollection):
child.set_color('k')
child.set_hatch('//')
It appears that it isn't really possible to change this color under the current seaborn implementation. This is because they pass the color of the main line explicitly to the error band as ax.fillbetweenx(... color=original_color). After playing around in the past, I found that this color arg seems to supersede the other color arguments such as facecolor and edgecolor, thus it doesn't matter what you put in there in the err_kws. However you could fix it by editing line 810 in site-packages/seaborn/relational.py from:
ax.fill_between(x, low, high, color=line_color, **err_kws)
to
ax.fill_between(x, low, high, **err_kws)
and passing the colors explicitly through err_kws.

Using plt.show() how can I define the background color?

When I visualize a plot, the default background color is something like gray. I want to have a white end, like the one that I obtain when I save the plot.
Like any other patch, the figure itself has a set_facecolor() method.
fig = plt.figure()
fig.set_facecolor("w")
You may also directly use the facecolor argument of plt.figure()
fig = plt.figure(facecolor="w")
A third option is to set the respective rc Parameter. This can either be done in the top of the script
plt.rcParams["figure.facecolor"] = "w"
or by chaning the matplotlib rc file.
Note that from matplotlib version 2.0 on, the default facecolor for figures is actually white, so updating matplotlib is the fourth option available.

How do I switch to the new color map in matplotlib 1.5?

I want to write a line to switch all my plots to the new color map (viridis), how do I do that?
There's a lot of information on the new available colors http://matplotlib.org/users/colormaps.html, there's information on how to pick a style with the style.use("ggplot") http://matplotlib.org/users/style_sheets.html, and there's a page saying that the new color map is changing http://matplotlib.org/style_changes.html#. On none of those do they say how to actually switch to a different colormap...
In matplotlib, the "styles" control much, much more than just the colormap.
To configure one aspect of the style on the fly, use:
import matplotlib
matplotlib.rcParams['image.cmap'] = 'viridis'
In the forthcoming v2.0 release of matplotlib, viridis will be the default colormap and this won't be necessary. Lots of other stylistic changes will be in place as well. You can look at those here:
http://matplotlib.org/devdocs/gallery.html
To look at the available styles, inspect the available list:
from matplotlib import pyplot
pyplot.style.available
For the new default color cycle, you'd do:
from cycler import cycler
colors = [
'#1f77b4', '#ff7f0e', '#2ca02c',
'#d62728', '#9467bd', '#8c564b',
'#e377c2', '#7f7f7f', '#bcbd22',
'#17becf'
]
matplotlib.rcParams['axes.prop_cycle'] = cycler('color', colors)

Style of error bar in pandas plot

I'd like to plot line chart with error bar with the following style.
However, pandas plot draws error bars with only vertical line.
pd.DataFrame([1,2,3]).plot(yerr=[0.3,.3,.3])
How do I change style of error bar for pandas plot?
The versions are:
pandas '0.18.0'
matplotlib '1.5.1'
Update
One of the reason seems using the seaborn style. The following code give the nice style plot.
# plt.style.use('seaborn-paper')
pd.DataFrame([1,2,3]).plot(yerr=[0.3,.3,.3],capsize=4)
But, I have a reason to keep using seaborn style... Please help.
You can change the capsize inline when you call plot on your DataFrame, using the capsize kwarg (which gets passed on to plt.errorbar):
pd.DataFrame([1,2,3]).plot(yerr=[0.3,.3,.3],capsize=4)
Alternatively, you can change this setting using rcParams
You can find out what your default errorbar cap size is by printing plt.rcParams['errorbar.capsize']. If that is 0 (which is why I suspect you are currently getting no errorbar caps), you can set the default size of the errorbar caps to something nonzero, using:
plt.rcParams['errorbar.capsize']=4
Make sure to have that at the beginning of any plotting script.
Update:
It seems using the seaborn-paper style sets the cap thickness to 0. You can override this with the capthick kwarg:
plt.style.use('seaborn-paper')
pd.DataFrame([1,2,3]).plot(yerr=[0.3,.3,.3],capsize=4,capthick=1)