matplotlib changed rendering style unexpectedly in jupyter-notebook - python

My matplotlib plots have changed styles unexpectedly. I am trying to pin down what I did to change them. My best guess is that I changed matplotlib versions, or I'm possibly am using a different backend.
A histogram plot currently looks like this:
They used to look like this (nice defined border lines between the bars):
I have made no changes to the code that generates the plots, but I have mucked with import statements, and re-installed various components of anaconda, including matplotlib for unrelated reasons.

Earlier this year, matplotlib changed their defaults. You want the edgecolor param.
plt.hist(np.random.norma(0,1,100), edgecolor='k')
You can use a classic style by passing plt.style.use('classic').

Starting from matplotlib version 2.0, patches do not have edges anymore. See the Changes to the default style.
Options to set edges back on:
Use the edgecolor argument of the artist. E.g.
plt.bar(...., edgecolor="k")
Use the rcParams to globally set edges,
plt.rcParams['patch.force_edgecolor'] = True
or edit you matplotlibrc file accordingly.
Turn the old style on again, using
plt.style.use('classic')

Related

Black background behind a figure's labels and ticks, only after saving figure but not in Python Interactive view (VS Code with Jupyter functionality)?

I have a strange problem where if I save a figure, its labels and ticks will have a black background, see this example:
plt.savefig("asdsadsad.png")
I'm not even including any code here because this happens on the simplest plotting, even with code that I made earlier with a different computer that never had this problem. I'm using VS Code with Jupyter functionality and the figures look normal in the Python Interactive view, but have the black border when saved.
Any ideas what could cause this strange problem?
plt.savefig will not use the same settings that you plotted with. That's why the saved image might look different from what you have plotted in Python. To define the background color of your figure, you need to define the facecolor parameter when you call savefig.
plt.savefig('asdsadsad.png', facecolor='w')
Your default facecolor may be set to black in your rcParams
I think I got the same issue, besides having facecolor and edgecolor set to white ('w'). For some strange reason the problems occured only with PNG image format and shifting to JPG solved everything.

Plot-style of matplotlib

I'd like to know why matplotlib outputs plots in different styles depending on which system I run the file. For example, I let the same code run twice, once on a Windows machine and once on Ubuntu system, and got the following two plots
The information in the plots is obviously the same, but is there a special command to let matplotlib know that I'd, for example, would like all my plots to be produced in the "Ubuntu style" (lower of the two) version?
The upper plot is produced with a version of matplotlib >= 2.0. The lower plot is produced with a version < 2.0. The style changes are documented in the Changes to the default style.
It's hardly possible to make a matplotlib version < 2.0 produce the exact output you'd get with matplotlib >= 2.0, although you might copy the style sheet from a newer version to the old one and set the parameters accordingly.
The inverse is however possible. To get the old (classic) style in a new version of matplotlib should be possible via
import matplotlib.pyplot as plt
plt.style.use("classic")

How to set all edgecolor to none in Seaborn / Matplotlib?

I pass the edgecolor=none to the plot to make the edge of the graph disappear.
The whole code appears like this:
sns.countplot(x="Survived", data=titanic_df, ax=ax1, palette='Pastel1', edgecolor='none')
However, I have to do this everytime when I'm visualizing graphs which is annoying. How can I set seaborn / matplolib up to default edgecolor to none???
Thanks!
You seem to be using an older version of matplotlib. Matplotlib version 2.0 does not have edges on bars by default. Therefore an easy solution may be to update matplotlib and seaborn to the newest versions.
Essentially you are asking for the inverse of this question No outlines on bins of Matplotlib histograms or Seaborn distplots .
Using either of
plt.rcParams['patch.linewidth'] = 0
plt.rcParams['patch.edgecolor'] = 'none'
at the beginning of the script (but potentially after importing seaborn, if an older version of seaborn is used) should give the desired result of no edges on patches like bars.
If the edges disappear by some other mechanism and you are actually using matplotlib 2.0, you may need to set
plt.rcParams["patch.force_edgecolor"] = False
in addition.

imshow in subplot with interactive mode

I cannot get matshow() or imshow() to actually display the plot when both of the following conditions are true: (1) interactive mode is on: import matplotlib.pyplot as plot; plot.ion(), and (2) I am trying to use matshow on a specific subplot: fig = plot.figure(); ax = fig.add_subplot(111); ax.matshow([[1,2],[3,0]]).
Using plot.matshow([[1,2],[3,0]]) (note: no explicit axes) works find in interactive mode, but will always create a new figure window with a single axes object. The above code with the subplot also works fine without interactive mode using plot.show(), and will put the image on the correct axes.
More oddly, the above code with the subplot will show the image if I interact with the figure, such as by using the zoom tool and clicking randomly in the figure window (there is no visible axes object, but I just click somewhere in the middle of the figure window).
Any ideas what might be causing this, how I could fix it, or how I could get around it to use matshow or imshow on a specified subplot (the end use case is to have more than 1 subplot in the figure)? This occurs in python (2.7.6) and ipython (1.1.1)
This may have something to do with this documentation:
Display an array as a matrix in a new figure window.
However, you may as well use imshow with suitable arguments:
import matplotlib.pyplot as plt
plt.imshow(mat, interpolation='nearest', origin='upper', aspect='equal')
This should do the same thing while being a bit less odd. This is actually exactly what matshow does internally. It just adds a few tick markers to the image.
Also, by having a look at the source (or closely reading the help string), you may try to do:
plt.matshow(mat, fignum=0)
This should force it use current axis, which it picks by using gca.
In addition to this, there is ax.matshow which you used, as well. Actually plt.matshow is a very thin wrapper around ax.matshow, mostly to create the new image.
If you still have problems with matshow or imshow in subplots, please make a minimal complete example for us to try! Here is something I tried in the interactive shell (IPython):
figure()
ax = subplot(121)
ax2 = subplot(122)
ax.matshow(random.random((20,30)))
ax2.plot(linspace(-1,1,100), linspace(-1,1,100)**2)
draw()
(Could the problem be a missing draw?)
What I got:

What was the default color palette for images in seaborn version 0.2?

A thing I immediately liked about seaborn was that it set the Matplotlib default color palette for images (imshow, pcolormesh, contourf, ...) to a very good one I had not seen before (black-blue-green-brown-pink-purple-white):
plt.contourf(np.random.random((20,20)))
But when I upgraded the package from version 0.21 to 0.3, this default changed to some greyscale:
What is the default color palette from v. 0.2.1 called and how do I get it back?
The default color palette in seaborn v. 0.2.1 is Dave Green's 'cubehelix' and you can get it back in v. 0.3 via
import seaborn as sns
sns.set(rc={'image.cmap': 'cubehelix'})
A 'brute force' way of finding this out is rolling back to the old version and creating a default plot:
img = plt.contourf(np.random.random((20,20)))
print(img.cmap.name)
In fact, the default in seaborn is defined in this file in the seaborn repo. A look into the Matplotlib sample matplotlibrc file might also help to find the right parameters to adjust.
Just to add to j08lue's answer, the reason it changed is that it's pretty much impossible to choose a single default colormap that is appropriate for all kinds of data, and having a bad color map can cause lots of problems. The hope it that by making the default a grayscale map, it will encourage people to think about their data and choose the right kind of map.
By the way all (most?) matplotlib functions that plot with a colormap will take a cmap keyword argument, i.e. plt.contourf(x, y, z, cmap="cubehelix") will work.

Categories

Resources