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

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)

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:

How to remove marker edges in seaborn.pairplot()?

Seaborn has a handy function pairplot to create a matrix of scatter plots. Unfortunately, some standard matplotlib commands don't work with it.
sns.pairplot(matrix[cols[:4]].head(100), plot_kws=dict(alpha=.5, mew=0))
The markers get some ugly white edges. I tried mew for markeredgewidth keyword to remove them as it would be used in matplotlib, but that is an unknown property for seaborn. How can I remove these edges?
A scatter does not have a mew keyword. It is edgecolor instead. Hence
sns.pairplot(data, plot_kws=dict(edgecolor="none"))
would remove the white edge around the scatterpoints.
ImportanceOfBeingErnest's answer is much more precise. Alternatively, you can also use a workaround: Set the color of choice for both the face and the edges of the markers as (example from the docs)
import seaborn as sns
sns.set(style="ticks", color_codes=True)
iris = sns.load_dataset("iris")
g = sns.pairplot(iris, plot_kws=dict(facecolor='b', edgecolor="b"))
EDIT based on comments below IOBE's answer: Just specifying the linewidth=0 also works the same way on markers as specifying edgecolor="none".
g = sns.pairplot(iris, plot_kws=dict(linewidth=0))

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.

Use a different matplotlibrc for savefig

I am using Jupyter Notebook, with a matplotlibrc style that's consistent with its theme set using jupyterthemes. That plotting style however does not look good if I want to export it to PNG to use it within my other documents.
How do I specify a different matplotlibrc when I do a savefig?
Most matplotlib style settings are applied at the moment the object they apply to is created.
You would hence need to create two different plots, one with the usual style of your notebook and another one with the style from the style file. The latter one would be the one to save.
A decent solution would be to create a plot in a function. You can then call this function within a context, with plt.style.context(<your style>): to give the figure a different style.
import matplotlib.pyplot as plt
def plot():
fig, ax = plt.subplots()
ax.plot([2,3,4], label="label")
ax.legend()
# Plot with general style of the notebook
plot()
# Plot with your chosen style for saved figures
with plt.style.context('ggplot'):
plot()
plt.savefig("dark.png")
#plt.close(plt.gcf()) # if you don't want to show this figure on screen
plt.show()
Relevant here: The matplotlib customizing guide.
Perusing matplotlib/__init__.py reveals a number of functions used for managing rcParams. To update rcParams from a file, use matplotlib.rc_file:
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rc_file('/tmp/matplotlibrc')
plt.plot([0,1], [0,10])
plt.savefig('/tmp/out.png')
with /tmp/matplotlibrc containing
lines.linewidth : 10 # line width in points
lines.linestyle : -- # dashed line
yields
PS. In hindsight, having found rc_file, googling shows it is documented here.

Change default background color for matplotlib plots

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('...').