Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Help tool #9022

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
adding help tool
  • Loading branch information
Federico Ariza authored and fariza committed Apr 12, 2018
commit 38d83af6e5d02063eaac5d158eefbd0eca97e616
67 changes: 66 additions & 1 deletion lib/matplotlib/backend_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

from matplotlib import rcParams
from matplotlib._pylab_helpers import Gcf
from matplotlib.table import Table
import textwrap
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move the import down per PEP8

import matplotlib.cbook as cbook


Expand Down Expand Up @@ -1020,6 +1022,68 @@ def _mouse_move(self, event):
self.toolmanager.canvas.draw_idle()


class HelpTool(ToolToggleBase):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be ToolHelp for consistency (or rather all others should be FooTool, but heh).

description = 'Print tool list, shortcuts and description'
default_keymap = rcParams['keymap.help']
image = 'help.png'

def __init__(self, *args):
ToolToggleBase.__init__(self, *args)
self.text_axes = None

def enable(self, *args):
self.text_axes = self.figure.add_axes((0, 0, 1, 1))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should create the axes with a custom (internal) label (with a comment) to workaround #9024 (although that bad behavior is now deprecated), just in case.

table = Table(self.text_axes, bbox=[0, 0, 1, 1])
table.edges = 'B'
self.text_axes.add_table(table)
chars_in_width = self._find_chars_in_width(table.FONTSIZE)

table.auto_set_font_size(False)
col_chars_width = int(chars_in_width / 4) - 2
content = self._get_content(col_chars_width, col_chars_width,
2 * col_chars_width)
for i, v in enumerate(content):
h = v[0]
table.add_cell(i, 0, text=v[1], width=1, height=h, loc='left',
fontproperties='monospace')
table.add_cell(i, 1, text=v[2], width=1, height=h, loc='left',
fontproperties='monospace')
table.add_cell(i, 2, text=v[3], width=2, height=h, loc='left',
fontproperties='monospace')
self.figure.canvas.draw_idle()

def _find_chars_in_width(self, fontsize):
"""Number of characters in figure width approx"""
# https://web.archive.org/web/20010717031241/plainlanguagenetwork.org/type/utbo211.htmhttps://web.archive.org/web/20010717031241/plainlanguagenetwork.org/type/utbo211.htm
# Approximately width = 60% of height for monospace fonts
charwidth = 0.6 * fontsize / 72.0 * self.figure.dpi
figwidth = self.figure.get_figwidth() * self.figure.dpi
return figwidth / charwidth

def disable(self, *args):
self.text_axes.remove()
self.figure.canvas.draw_idle()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that after having pressed that button 10 times, you have 10 unused Axes in memory? Should it maybe rather reuse an existing axes, or comletely delete the unused axes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when creating the axes we specify the label, so if I understand it correctly it should reuse it if available

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That behavior (of reusing axes) is deprecated.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But's it's not available, because you removed it from the figure. And if you didn't remove it, it would cause a warning, telling you that creating an instance with the exact same arguments will return a new instance in the future.

Simple test case:

fig = plt.figure()
ax1 = fig.add_axes((0, 0, 1, 1), label='help_tool_axes')
ax1.remove()
ax2 = fig.add_axes((0, 0, 1, 1), label='help_tool_axes')
print(ax1==ax2)    # This will print False.

I think it would indeed be a good idea to reuse the axes, but I currently would not know how to do that. I.e. how would one add an axes to a figure which has previously been removed? (fig.add_axes(ax) does not seem to work.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create it once, call set_visible(True), call set_visible(False).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, now it creates it once, set the visibility to change.
I clear the axes before filling it because the tools are dynamic, so the content might change between different calls

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting the visibility lets the axes stay in fig.axes. This might change any program's complete logic depending on whether or not you are using the ToolManager to show the figure and whether or not you have previously toggled the help or not.

Simple example:

for ax in fig.axes:
    # do something.


def _get_content(self, w0, w1, w2):
rows = [(1, 'NAME', 'KEYS', 'DESCRIPTION')]
tools = self.toolmanager.tools
for name in sorted(tools):
if not tools[name].description:
continue

keys = ', '.join(sorted(self.toolmanager.get_tool_keymap(name)))
name_lines = textwrap.wrap(name, w0)
keys_lines = textwrap.wrap(keys, w1)
desc_lines = textwrap.wrap(tools[name].description, w2)
# Height of the row is the maximum number of lines
height = max(len(name_lines), len(keys_lines), len(desc_lines))
rows.append((height,
'\n'.join(name_lines),
'\n'.join(keys_lines),
'\n'.join(desc_lines)))
return rows


default_tools = {'home': ToolHome, 'back': ToolBack, 'forward': ToolForward,
'zoom': ToolZoom, 'pan': ToolPan,
'subplots': 'ToolConfigureSubplots',
Expand All @@ -1037,12 +1101,13 @@ def _mouse_move(self, event):
_views_positions: ToolViewsPositions,
'cursor': 'ToolSetCursor',
'rubberband': 'ToolRubberband',
'help': HelpTool
}
"""Default tools"""

default_toolbar_tools = [['navigation', ['home', 'back', 'forward']],
['zoompan', ['pan', 'zoom', 'subplots']],
['io', ['save']]]
['io', ['save', 'help']]]
"""Default tools in the toolbar"""


Expand Down
Binary file added lib/matplotlib/mpl-data/images/help.pdf
Binary file not shown.
Binary file added lib/matplotlib/mpl-data/images/help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added lib/matplotlib/mpl-data/images/help.ppm
Binary file not shown.
52 changes: 52 additions & 0 deletions lib/matplotlib/mpl-data/images/help.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added lib/matplotlib/mpl-data/images/help_large.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added lib/matplotlib/mpl-data/images/help_large.ppm
Binary file not shown.
1 change: 1 addition & 0 deletions lib/matplotlib/rcsetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -1420,6 +1420,7 @@ def _validate_linestyle(ls):
'keymap.yscale': [['l'], validate_stringlist],
'keymap.xscale': [['k', 'L'], validate_stringlist],
'keymap.all_axes': [['a'], validate_stringlist],
'keymap.help': [['f1'], validate_stringlist],

# sample data
'examples.directory': ['', validate_string],
Expand Down
3 changes: 2 additions & 1 deletion tools/make_icons.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ def make_matplotlib_icon():
('move', 0xf047),
('filesave', 0xf0c7),
('subplots', 0xf1de),
('qt4_editor_options', 0xf201)]
('qt4_editor_options', 0xf201),
('help', 0xf128)]


def make_icons():
Expand Down