15

I am using PyCharm 2016.1 and Python 2.7 on Windows 10 and imported the matplotlib module.

As the matplotlib module ist very extensive and I am relatively new to Python, I hoped the Auto Complete function in PyCharm could help me to get an overview of the existent properties/ functions of an object. It would be more convenient as digging through the api documentation every time, not knowing what to look for an where to find it.

For example:

from matplotlib import pyplot as plt
fig, ax = plt.subplots()

When I type ax. there ist no auto completion for the properties, functions etc. of the axis, I only get the suggestions list.

I already tried this and imported the axis module directly with:

import matplotlib.axis as axis

or

from matplotlib.axis import Axis as axis

Smart Auto Completion and 'Collect run-time types information' is already enabled.

Is there a way to enable the auto completion like described or is there another IDE that supports that?

Community
  • 1
  • 1
Triscus
  • 320
  • 1
  • 3
  • 12
  • Is your problem solved now? For me in Python 2.7 there is auto-complete for mpl, but not in python 3.6. – Alex May 09 '19 at 23:19

2 Answers2

15

I believe your problem is highlighted here:

https://intellij-support.jetbrains.com/hc/en-us/community/posts/205816499-Improving-collecting-run-time-type-information-for-code-insight?sort_by=votes

Tldr return types can vary, so it cant be figured out at compile time.

Most accepted way is to use a type hint, since it can only figure out what type it as run time :

import matplotlib.axes._axes as axes

fig = plt.figure(figsize=(5,10))
ax1 = fig.add_subplot(3,1,1) # type:axes.Axes
ax1.set_xlabel('Test') <- now autocompletes

You can also try an assert isinstance:

import matplotlib.axes._axes as axes

fig = plt.figure(figsize=(5,10))
ax1 = fig.add_subplot(3,1,1)
assert isinstance(ax1, axes.Axes)
ax1.set_xlabel('Test')

It wont find the autocomplete if you do it after the method you are looking for:

ax1.set_xlabel('Test')
assert isinstance(ax1, axes.Axes)

With this, you shouldnt let isinstance dictate the control flow of your code, if you are trying to run a method that doesnt exist on an object, it should crash, however, if your different object has a method of the same name (!) then you have inadvertently reached that goal without annotations being there. So I like it better, since you want it to crash early and in the correct place. YMMV

From the doc:

Assertions should not be used to test for failure cases that can occur because of bad user input or operating system/environment failures, such as a file not being found. Instead, you should raise an exception, or print an error message, or whatever is appropriate. One important reason why assertions should only be used for self-tests of the program is that assertions can be disabled at compile time.

If Python is started with the -O option, then assertions will be stripped out and not evaluated. So if code uses assertions heavily, but is performance-critical, then there is a system for turning them off in release builds. (But don't do this unless it's really necessary.

https://wiki.python.org/moin/UsingAssertionsEffectively

Alternatively, if you dont want to add to your code in this fashion, and have Ipython/jupyter installed through anoconda, you can get the code completion from the console by right clicking the code to be ran and choosing "execute selection in console"

Community
  • 1
  • 1
Paul Stanley
  • 4,018
  • 6
  • 35
  • 56
  • 1
    See if it wasn't [this](https://stackoverflow.com/a/60874856/4465708) – z33k Mar 26 '20 at 19:38
  • Type hints are a hack rather than a solution imho. One can arbitrarily hint to ANY type and be very wrong. If I share this wrongly type hinted code with someone else, they will get autocomplete options for the wrong type. Furthermore its often not known how to type hint due to lacking documentation, or lack of type hinting on the returns of a given method. As there are so many dynamically created methods and attributes in matplotlib, the only real way to find these is via an interactive shell. – topher217 Dec 02 '21 at 07:31
  • Interactive shells are great for trying simple things things out, but I don't know a good way to use them with larger code bases. For example how are you supposed to write multi-threaded/processed code? You can't just stop one thread and expect everything to behave as it would had you not stopped a thread/process. I still am looking for an efficient way to write non-trivial python code... – topher217 Dec 02 '21 at 07:34
4

In addition to Paul's answer. If you are using fig, ax = plt.subplots() , you could use figure type hint. See below example:

from matplotlib import pyplot as plt
import matplotlib.axes._axes as axes
import matplotlib.figure as figure

fig, ax = plt.subplots()  # type:figure.Figure, axes.Axes
ax.
fig.
Carlos Cordoba
  • 33,273
  • 10
  • 95
  • 124
Mahmoud
  • 81
  • 4