For some reason this code creates a figure that is only the standard size: it doesn't change the height or width (I chose widths and heights that are ludicrous to clearly illustrate the problem):
import matplotlib.pyplot as plt
fig = plt.figure()
fig.set_figwidth(30)
fig.set_figheight(1)
print('Width: {}'.format(fig.get_figwidth()))
plt.show()
I'm running on OSX 10.10.4, Python 3.4.3, Matplotlib 1.4.3. (Installed via Macports.) Any ideas? What am I missing?
The optional parameter forward propagates changes to the canvas in a GUI window that already exists.
Documentation here:
optional kwarg forward=True will cause the canvas size to be automatically updated; e.g., you can resize the figure window from the shell
Using Figure(figsize=(w,h)) also works.
For Matplotlib 2.2.0 and newer
forward=True is the default for all three of set_figheight, set_figwidth, and set_size_inches (set_size_inches changes both height and width simultaneously).
For Matplotlib 1.5.0
forward=True must be specified explicitly as it is False by default. (In Matplotlib 2.0.0, the default is changed to True only for set_size_inches).
For Matplotlib 1.4.3 and older
forward is only supported by set_size_inches.
set_figheight and set_figwidth do not support this argument, so it is a bit difficult to only change a single dimension of a pre-created GUI.
I'm not certain why those documented functions don't work, but they have been fixed for the next matplotlib release (>v1.4.3). As a workaround until the next release, replacing set_figwidth and set_figheight solves this problem.
import matplotlib.pyplot as plt
fig = plt.figure()
# Instead of set_figwidth(30)
fig.set_size_inches(30, fig.get_figheight(), forward=True)
plt.show()
Related
I'm using Spyder v5 within Anaconda and having issues with any styles being applied on charts. Basic chart below (deliberately commented out the sns import to see if it makes any difference -it doesn't)
Basic code below - gives a normal plot as expected
import matplotlib.pyplot as plt
#import seaborn as sns
x_values = [0,1,2,3,4,5,6,7,8,9,10]
x_squared = [x ** 2 for x in x_values]
plt.plot(x_values,x_squared, label = "X-Squared")
plt.plot(x_values,x_cubed, label = "X-Cubed")
plt.show()
If i then try
plt.style.use("seaborn-deep")
plt.plot(x_values,x_squared, label = "X-Squared")
plt.plot(x_values,x_cubed, label = "X-Cubed")
plt.show()
Nothing changes? The style is avaialble (from plt.styles.available) and there is no error when applying the style so something is amiss here.
If i import seaborn then nothing changes
If i try any or all of the following from other solutions in various places in my plt code then nothing much changes (all of the below lines of code work with no errors
%matplotlib inline
plt.rcParams.update(plt.rcParamsDefault)
sns.set()
One time somehow this did seem to force it to change to a seaborn-paper style but that's then the only one i can use and i can't use any other seaborn or other styles at all?? Not sure what forced it to change, think it was sns.set() so I suspect the one it then shows is the default seaborn style, but then why won't it let me use any other styles?
As i'm using SPyder in anaconda the packages are installed to do this plot
I do have Python installed on my base desktop as well... but documentation insists this won't cause a problem and i've not had this problem on any other code ever of having another installation
any tips?
Problem
I cannot seem to get savefig() to actually save a PNG file without a transparent figure background.
This is having read and tried all the suggestions previously posted, answered, cursed about and also going through the API docs a bunch of times. I've read it all, but still can't get non-transparent figure faces
Background
I'm using matplotlib and savefig to create a PNG file. (env: macos - latest anaconda modules using PY 3.7).
I am trying this out of jupyter however - so hopefully it's not something completely screwed up with only how ipython in jupyter does it - though I don't see how that could be the case
I did read through the previous many posts about the (confusing as hell) nature of savefig doing it's own thing with backgrounds, and did/tried everything as suggested (and as written in the latest savefig api docs).
In particular, I've tried all the following without sucess:
specifying facecolor in the savefig() call (with/without transparency)
savefig.facecolor: white in the style mpl file I'm using
When savefig'ing my figure background is always transparent.
Can anyone tell me what the !##$!# I'm missing here???
Code
Here's what I''m using, which spits out figure with transparent background, regardless of what I do.
In particular the 2nd call below (with savefig(..., transparent=False)) will make the axes not transparent - but the figure itself is still transparent!)
import numpy as np
import matplotlib as mpl
import matplotlib.style as style
a = np.array([-3.2, 0.1, 1.5, 3.3, 8.5])
b = np.array([1.1, 1.8, 1.95, 2.3, 4.3])
labels = ['a', 'bc', 'def', 'g', 'ggghhh']
stylefile = './util/plot_config/aqs_default.mplstyle'
# the file above does contain an entry of:
# savefig.facecolor: white
#
to_res = 1024
dpi = 100
inches = (to_res/dpi, to_res/dpi)
style.use(stylefile)
%matplotlib
fig = mpl.figure.Figure(figsize=inches, dpi=dpi, facecolor='white')
ax = fig.subplots()
for x, y, l in zip(a,b,labels):
ax.scatter(x,y,label=l)
ax.legend()
ax.set_xlabel('Some x')
ax.set_ylabel('Attenuation $\mu$ (cm$^{-1}$)')
ax.set_title('blah', y=1.03)
fig.suptitle('Linearity $\mu$')
# for me, _both_ calls below result in the figure having a transparent background:
fig.savefig('a.png', facecolor=fig.get_facecolor(), transparent=True)
fig.savefig('b.png', facecolor=fig.get_facecolor(), transparent=False)
Unfortunately, it seems that frameon is not supported anymore as of matplotlib 3.3.
I solved the transparency issue by setting facecolor='white', transparent=False options in savefig()
FYI for anyone else with a similiar problem.
The cause (and fix) turned out to be because I was creating a figure with frameon set to False.
I had actually had this set to False in a style file I was using.
Changing frameon to True fixed the problem.
This was confusing and not very obvious at all from any documentation - here is some background on the issue from the MPL github issues:
https://github.com/matplotlib/matplotlib/issues/14339
I have made the following script, let's call it test-matplotlib-printbackend.py:
#!/usr/bin/env python
import matplotlib as mpl
import matplotlib.pyplot as plt
xx = range(100)
yy = [i*2+5 for i in xx]
fig, ax = plt.subplots()
ax.plot(xx, yy)
print("Matplotlib plt backend: {}".format(plt.get_backend()))
plt.show()
For Python3 under MINGW64 on Windows 10, as well as Python3 under Anaconda on Windows 10, I get the printout:
Matplotlib plt backend: Qt5Agg
However, for Python3 on Rasbian (Raspberry Pi's Debian OS), I get the printout:
Matplotlib plt backend: TkAgg
This kind of puzzles me, because I sort of expected TkAgg would be the default GUI backend for matplotlib on all platforms !?
So, I just wanted to know - is the default GUI backend for Matplotlib for different platforms documented anywhere?
The backend selection logic is not very transparent and not well documented.
In modern matplotlib there is no "default backend", i.e. the rcParams['backend'] is set to a "sentinel".
Upon importing matplotlib the first working backend from a candidate list ["macosx", "qt5agg", "qt4agg", "gtk3agg", "tkagg", "wxagg"] is chosen.
In order to avoid this automatic selection, you can set the backend manually via the rcParams['backend'] parameter or the MPLBACKEND environment variable. That part is documented
The default backend is defined in the mpl.rcParams['backend']. On Linux_x64 this is set to 'Qt5Agg'. The _get_running_interactive_framework function in the matplotlib.backends.__init__ checks for available backends. PyQt5 is highest in the priority list. The pyplot.switch_backend function uses _get_running_interactive_framework to select the effectively used backend on import. Search for the line switch_backend(rcParams["backend"]) here: https://matplotlib.org/3.1.1/_modules/matplotlib/pyplot.html
You could check whether PyQt5 is available on Rasbian and what the rcParams entry is.
I am trying to learn python mainly for plotting. Here is my sample code:
import numpy as np
import matplotlib.pyplot as plt
a=[[1,2,3,4],[2,3,4,5],[3,4,5,6]]
x=np.arange(len(a[0]))
width=0.2
fig, ax = plt.subplots(figsize=(8,6))
patterns=['/','\\','*']
for bar in a:
ax.bar(x,bar,width,edgecolor='black',color='lightgray', hatch=patterns.pop(0))
x=x+width
plt.show()
Now the problem is that, I need black edge colour for all bars as well as given hatch patter. However, the formatting is applied to first set of bars only. Here is my output. (I am using python3).
What's missing here or what's wrong? I have looked around but did not find any fix.
Update:
I have tried different options :python2, python3 and pdf/png. Here are results
python2 png --fine
python3 png -- shown above
python2 pdf -- see
python3 pdf -- see
I have also tried 'backend' as matplotlib.use('Agg'). I have update my matplotlib version (2.1.0).
There is a current issue in matplotlib 2.1 that only the first bar's edgecolor is applied. The same for the hatch, see this issue. Also see this question.
It may be that you are using matplotlib 2.1 for python3 but not for python2, hence in python2 it works for you. If I run your code in python 2 with matplotlib 2.1 I get the same undesired behaviour.
The issue will be fixed, once matplotlib 2.1.1 is released.
In the meantime, a workaround is to set the edgecolor and hatch on the individual bars:
import numpy as np
import matplotlib.pyplot as plt
a=[[1,2,3,4],[2,3,4,5],[3,4,5,6]]
x=np.arange(len(a[0]))
width=0.2
fig, ax = plt.subplots(figsize=(8,6))
patterns=['/','\\','*']
for y in a:
bars = ax.bar(x,y,width,color='lightgray')
hatch= patterns.pop(0)
for bar in bars:
bar.set_edgecolor("black")
bar.set_hatch(hatch)
x=x+width
plt.show()
It looks something's wrong with edgecolor tuple's alpha value. Set it to 1 will solve the problem.
Especially when working with grayscale images it is tedious to set the color map for every imshow command as imshow(i, cmap='gray'). How can I set the default color map matplotlib uses to grayscale or any other colormap?
To change the default colormap only for the current interactive session or one script use
import matplotlib as mpl
mpl.rc('image', cmap='gray')
For versions of matplotlib prior to 2.0 you have to use the rcParams dict. This still works in newer versions.
import matplotlib.pyplot as plt
plt.rcParams['image.cmap'] = 'gray'
To change the default colormap permanently edit the matplotlibrc configuration file and add the line image.cmap: gray.
Replace the value gray with any other valid colormap according to your needs.
The config file should be at ~/.config/matplotlib/matplotlibrc, but you can find out the exact location with
mpl.matplotlib_fname()
This is especially useful if you have multiple matplotlib versions in different virtual environments.
See also http://txt.arboreus.com/2014/10/21/how-to-set-default-colormap-in-matplotlib.html
and for general configuration of Matplotlib http://matplotlib.org/users/customizing.html
You can do either,
plt.set_cmap('jet')
or
plt.rcParams['image.cmap']='jet'
However note that if you are passing value for color parameter in any of the APIs then this default will be ignored. In that case you should do something like this:
color = plt.cm.hsv(r) # r is 0 to 1 inclusive
line = matplotlib.lines.Line2D(xdata, ydata, color=color)