Remove toolbar buttons in matplotlib - python

I'm trying to remove all toolbar buttons except 'save' button.
I managed to remove the buttons but I couldn't find a way to remove the 'Configure subplots' button.
Here is a simple code just to illustrate how i tried to remove the buttons:
import matplotlib.pyplot as plt
plt.rcParams['toolbar'] = 'toolmanager'
# I managed to find the buttons' names while reading the backend_bases.py
# I didn't find the subplot configuration button name so i didn't include it here
buttons_names = ['forward', 'back', 'pan', 'zoom', 'home', 'help']
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot([1, 2], [1, 2])
# removing buttons using
for button in buttons_names:
fig.canvas.manager.toolmanager.remove_tool(button)
plt.show()
I looked at backend_bases.py and commented the subplots tuple which now looks like this: (I don't know if there is a reference to 'subplots configuration' button somewhere else in order to remove the button)
toolitems = (
('Home', 'Reset original view', 'home', 'home'),
('Back', 'Back to previous view', 'back', 'back'),
('Forward', 'Forward to next view', 'forward', 'forward'),
(None, None, None, None),
('Pan', 'Pan axes with left mouse, zoom with right', 'move', 'pan'),
('Zoom', 'Zoom to rectangle', 'zoom_to_rect', 'zoom'),
#('Subplots', 'Configure subplots', 'subplots', 'configure_subplots'),
(None, None, None, None),
('Save', 'Save the figure', 'filesave', 'save_figure'),
)
Also when i run the code above, it also shows a warning:
UserWarning: Treat the new Tool classes introduced in v1.5 as experimental for now, the API will likely change in version 2.1, and some tools might change name
'experimental for now, the API will likely change in ' +
I looked at other solutions but none worked for me, and some of them use gui frameworks which is not what i'm looking for.
Is there any other way that can remove the button, or is there a name for subplots configuration button that i can include in the buttons_names list in the code above?
Update: Ok, it seems that the problem was associated with python version. I was using python 3.7.0. I updated to 3.7.4, added 'subplots' to buttons_names list and it worked. But there are 2 issues:
When the chart is shown, it displays a warning:
Treat the new Tool classes introduced in v1.5 as experimental for now, the API will likely change in version 2.1 and perhaps the rcParam as well
C:/Users/usr/Documents/MyPrograms/Python/Daily Expense/Chart.py:36: UserWarning: The new Tool classes introduced in v1.5 are experimental; their API (including names) will likely change in future versions.
fig = plt.figure()
The toolbar is now shown on top, it used to be under the chart and i want to make it display under the chart as it used to.
Currently i'm using Python 3.7.4, matplotlib version 3.1.1, Windows 10
How can i fix these 2 things?

Apparently the name is "subplots":
fig.canvas.manager.toolmanager.remove_tool("subplots")

Re part 1 of your question, I've been able to suppress that annoying warning by doing this:
import sys
import matplotlib.pyplot as plt
if not sys.warnoptions:
import warnings
warnings.filterwarnings("ignore", category=UserWarning,
message="Treat the new Tool classes introduced in v1.5 as experimental for now")
plt.rcParams['toolbar'] = 'toolmanager'
You may have to edit the value of the message arg if the warning message changes with later matplotlib versions though. See the Python docs for the Warnings Filter.

Related

Removing tool bar and figure title when using jupyter-matplotlib

I'm using jupyter-matplotlib to embed charts as widgets in a jupyter widgets based dashboard. However, I would like to disable the interactive tool bar and the figure title that automatically gets added.
As a simple example, the below creates an empty figure but it still has the interactive tool bar and Figure title.
%matplotlib widget
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
I would like to remove both the tool bar and figure title as well as anything else that is added padding around the plot, which I may not be able to see.
If you are using the latest jupyter-matplotlib version (0.5.3 as I am writting), you can use:
fig.canvas.toolbar_visible = False
fig.canvas.header_visible = False
fig.canvas.footer_visible = False
You can also disable the resizing:
fig.canvas.resizable = False
To get rid of toolbar you can use this
mpl.rcParams['toolbar'] = 'None'
To remove title you can set the title to me empty something like this
fig.set_title("")
Hope this helps!

Change default matplotlib value in jupyter notebook

I was wondering how you can change the matplotlib.rcParams permanently instead of indicating it every time when you open jupyter notebook. (like change in the profile as the default value).
Thanks
A short answer, also for personal reference...
I would still prefer indicating it in the code though. However it doesn't have to be done for every single parameters as it can be done in one line calling for a style file for instance.
Anyway, here are several ways of doing so, from the most permanent change to the most soft and subtle way of changing the parameters:
1. Change default config file
Change the default parameters in matplotlibrc file, you can find its location with:
import matplotlib as mpl
mpl.get_configdir()
2. Modify iPython profile
Change how matplotlib default options are loaded in iPython by modifying options in ~/.ipython/profile_default/ipython_kernel_config.py, or wherever your configuraiton file is (ipython locate profile to find out) (see this answer for details)
3. Create your own styles
You can create your own custom rcParams files and store them in .config/matplotlib/stylelib/*.mplstyle or wherever os.path.join(matplotlib.get_configdir(), stylelib) is.
The file should be in the following format, similar to matplotlibrc, e.g. my_dark.mplstyle:
axes.labelcolor: white
axes.facecolor : 333333
axes.edgecolor : white
ytick.color : white
xtick.color : white
text.color : white
figure.facecolor : 0D0D0D
This is an example of a style for a dark background with white axes, and white tick labels...
To use it, before your plots, call:
import matplotlib.pyplot as plt
plt.style.use("my_dark")
# Note that matplotlib has already several default styles you can chose from
You can overlay styles by using several ones at once, the last one overwrites its predecessors' parameters. This can be useful to keep e.g. font variables from a certain style (paper-like, presentation) but simultaneously toggle a dark mode on top, by overwriting all color-related parameters.
With something like plt.style.use(["paper_fonts", "my_dark"])
More info in their documentation.
4. Context manager for rc_params
You can also use a context manager, this option is great in my opinion, to do something like:
import matplotlib as mpl
import matplotlib.pyplot as plt
with mpl.rc_context(rc={'text.usetex': True}, fname='screen.rc'):
plt.plot(x, a)
plt.plot(x, b)
Here we used a first set of parameters as defined in the file screen.rc then tweak the text.usetex value solely for the plt.plot(x,a) while plt.plot(x, b) will be using another (default here) set of rc parameters.
Again, see the doc for more information.

Matplotlib Figuresize being ignored by rcParams

I have previously used the following to ensure my figure-size in my plots is a consistent size:
import matplotlib as mpl
rc_fonts = {'figure.figsize': (15, 9.3)}
mpl.rcParams.update(rc_fonts)
import matplotlib.pylab as plt
However, I am now finding that for my usual default values (15, 9.3) this is being ignored. The following demonstrates this:
import matplotlib as mpl
rc_fonts = {'figure.figsize': (15, 9.3)}
mpl.rcParams.update(rc_fonts)
import matplotlib.pylab as plt
# I draw some boring plot.
plt.clf()
plt.plot(*[range(10)]*2)
print plt.gcf().get_size_inches()
print mpl.rcParams['figure.figsize']
plt.gcf().set_size_inches(15, 9.3, forward=True)
print plt.gcf().get_size_inches()
The initial plot size is [10.35, 9.3] and after it is [15, 9.3] as desired. If however I make the default very much large or smaller, e.g. (32, 19.3) then the figure window is correctly sized. I would like to keep my desired route of changing rcParams to set the default, rather than trying to set it twice by making an interim dummy plot. Is this a bug, or am I going about this the wrong way?
Details:
Python 2.7.12 (inside a virtual environment, a must).
Backend TkAgg (I want this kept as it is).
Matplotlib version 2.1.0. (This bug/feature persists in version 2.1.2 also).
PS - I prefer avoiding having to make matplotlib fig and ax objects and instead use the plt interface directly. If possible I would like to keep it this way with any solutions.
Possible known issue:
I have found the following issue 2716 on github which I think is causing this, but there don't appear any fixes suitable for the rcParam settings route. So any help or suggestions are still welcome.
Current output:
Following the comments below is some example output (done using Python 3 to allow me to install the latest version of matplotlib):
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
>>>
... import matplotlib as mpl
... print(mpl.__version__)
... rc_fonts = {'figure.figsize': (15, 9.3)}
... mpl.rcParams.update(rc_fonts)
... import matplotlib.pylab as plt
... plt.plot(*[range(10)]*2)
...
Backend Qt4Agg is interactive backend. Turning interactive mode on.
2.2.0rc1+124.gf1f83f6
>>>
... print(plt.gcf().get_size_inches())
... print(mpl.rcParams['figure.figsize'])
... plt.gcf().set_size_inches(15, 9.3, forward=True)
... print(plt.gcf().get_size_inches())
...
[ 10.35 9.3 ]
[15.0, 9.3]
[ 15. 9.3]
DEMONSTRATION
Root of the problem
As explained in the accepted answer, the issue is that I am using more than one display, and Matplotlib cannot produce a window that is larger than the primary display. Unfortunately changing what Ubuntu considers to be the primary display is currently an unresolved bug. Hence the problem does not lie with Matplotlib, but with Ubuntu. I was able to resolve this issue by setting the display to the top left monitor in my setup.
The problem occurs because there are several screens in use and the one the figure is shown in is not the primary one.
There is currently no way to automatically show the figure larger than a maximized window on the primary screen would allow for. If the figure is larger than that, it is still shrunk to fit the plotting window.
After the window is initiated, one may indeed resize the figure to any other size, as is being done in the question using
plt.gcf().set_size_inches(15, 9.3, forward=True)

matplotlibrc rcParams modified for Jupyter inline plots

I have seen this question come up a couple of times, but I think this information changes as jupyter/ipython get updated. I am currently running python 3.5, jupyter (latest) and matplotlib 2.0.
The %matplotlib inline plots have custom properties that are set after the matplotlibrc file is imported. The most annoying of these is that the figure.facecolor property is set to be transparent which wreaks havoc when copy/pasting plots so I have to reset this property in the notebook. I cannot seem to find where this property is changed, or if it is possible to create a configuration profile somewhere to change these special inline plot settings
My question is, is it possible to change these settings, and if so, how would I do that?
Some of the rcParameters are set specifically for the inline backend. Those are
{'figure.figsize': (6.0,4.0),
'figure.facecolor': (1,1,1,0), # play nicely with white background in the Qt and notebook
'figure.edgecolor': (1,1,1,0),
'font.size': 10, # 12pt labels get cutoff on 6x4 logplots, so use 10pt.
'figure.dpi': 72, # 72 dpi matches SVG/qtconsole
'figure.subplot.bottom' : .125 # 10pt still needs a little more room on the xlabel
}
And the place where they reside is the ipykernel/pylab/config.py file.
This file can be edited to obtain the desired behaviour, e.g. by changing the facecolor to 'figure.facecolor': (1,1,1,1) (no transparency).
Another option is the following:
The rcParameters are defined as part of the InlineBackend class, specifically the InlineBackend.rc attribute which is a traitlets.Dict object.
Those can be changed using the ipython configuration system as follows.
From the command line type ipython profile create which will generate the default configuration files in ~/.ipython. In the main configuration file ~/.ipython/ipython_config.py include the line:
c.InlineBackend.rc.update({"figure.facecolor": "white"})
The accepted answer was correct at the time. Recent update: The inline-specific backend will no longer override Matplotlib's defaults, see this commit from 12th of May 2022.
Before this recent change, the dict with the override values had moved to
matplotlib-inline/matplotlib_inline/config.py

Matplotlib "pick_event" not working in embedded graph with FigureCanvasTkAgg

I'm trying to handle some events to perform user interactions with embedded subplots into a Tkinter frame. Like in this example
Works fine with "key_press_event" and "button_press_event", but does not work with "pick_event".
I modified that example from the link, just adding the following piece of code after the mpl_connect calling:
def on_button_press(event):
print('you pressed mouse button')
canvas.mpl_connect('button_press_event', on_button_press)
def on_pick(event):
print('you picked:',event.artist)
canvas.mpl_connect('pick_event', on_pick)
Why "pick_event" doesn't work into embedded graphs? And how do get it to work?
My configurations detailed:
Windows 10
Python 3.5 (conda version)
Matplotlib 1.5.3 installed via pip
Thanks in advance!
Well, I solved it...
Most events we just need to use mpl_connect method to the magic happen. My mistake is that I didn't notice that we need to say explictly that our plot is "pickable" putting a argument picker=True to only triggers the event if clicked exacly into the artist, and picker=x where x is an integer that is the pixel tolerance for the trigger. So beyond the changes I inserted for pick in the question, we should replace
a.plot(t, s) for a.plot(t, s,picker=True) or a.plot(t, s,picker=10), e.g.

Categories