I am just trying to set the axis limits with pyplot, but it seems like it is not detecting the argument of the axis function correctly, as it returns this error:
TypeError: 'list' object is not callable.
It is related to the axis function, but I can not see where the problem is. The part of my code which is giving the problem is the following:
plt.figure(1)
plt.plot(x[:,0],x[:,1])
ax=[0.0,10.0,0.0,10.0]
plt.axis(ax)
If I use x = numpy.random.randn(10,2) then the remainder of this code works with no issue, using NumPy 1.4, matplotlib 1.1.1, and Python 2.7.3. The axis function in the pyplot API accepts a list of 4 values as the first positional argument, so the usage here is correct. The error you are experiencing does not come from this piece of code.
If you provide the full details of the data you are trying to plot and the full details of the code and traceback message, perhaps we can help you.
# Works fine assuming packages are installed...
import numpy as np
import matplotlib.pyplot as plt
x = np.random.randn(10,2)
plt.figure(1)
plt.plot(x[:,0], x[:,1])
ax = [0.0, 10.0, 0.0, 10.0]
plt.axis(ax)
plt.show()
Given the error message you've posted, one possibility is that you have taken the instance of a list object (the thing called ax in your code) that was intended to serve as the boundary of an axis and confused it with the API function axis. In that case, look in your code for a place where you put the function call syntax after the variable name of ax, such as:
ax(x1, x2, y1, y2)
instead of
plt.axis(x1, x2, y1, y2)
In the first case, trying to "call" ax with some arguments will not succeed, since the Python list class does not implement the __call__ protocol, so that suffixing the function call symbols, () (potentially with arguments) after the variable name of a variable that is an instance of list will cause the error you are seeing.
Other things may cause it too, but this is my best guess given the limited info available in the question.
Related
I am using the function described here to get some diagnostics on multiple linear regressions.
The last code line reads # Fig and ax can be used to modify axes or plot properties after the fact.
My code:
cls = LRD(lm6_fit)
f,ax = cls();
Now, I have tried so many different ways to change the size of the figure but nothing worked...
if I run f? I some information about f, such as:
Type: Figure
String form: Figure(1000x1000)
Attributes
----------
patch
The `.Rectangle` instance representing the figure background patch.
suppressComposite
For multiple images, the figure will make composite images
depending on the renderer option_image_nocomposite function. If
*suppressComposite* is a boolean, this will override the renderer.
Init docstring:
Parameters
----------
figsize : 2-tuple of floats, default: :rc:`figure.figsize`
Figure dimension ``(width, height)`` in inches.
But I'm not sure how to modify the parameter figsize existing in f. I tried f.set_size_inches(K,L), for different values of K and L, but nothing changes.
I'm trying to make an animation with matplotlib, in this case a 3D scatter plot. I'm hitting a problem that I absolutely always hit when I try to do this, which is that I don't know what arguments I should pass to set_data, and I don't know how to find out. In this case, it apparently expects two arguments, despite it being a 3d plot.
Since I've experienced related problems often, rather than asking about the specifics of the particular plot I'm trying to animate, I will ask the general question: given an element of a MatPlotLib plot, how can I determine what arguments its set_data method expects, either by interrogating it, or by knowing where it's documented?
From an example for an Animated 3D random walk from the MatPlotLib documentation:
def update_lines(num, dataLines, lines):
for line, data in zip(lines, dataLines):
# NOTE: there is no .set_data() for 3 dim data...
line.set_data(data[0:2, :num])
line.set_3d_properties(data[2, :num])
return lines
So as confusing as you discovered it is set_data by itself is not meant for 3D data, as well as according to the docs it accepts:
2D array (rows are x, y) or two 1D arrays
Looking more at this example we can see that the set_3d_properties has been used altogether.
This whole update_lines was set as a callback parameter for animation.FuncAnimation.
Usually to find the documentation you can either search it up online (e.g doc for set_data) or from a python prompt you can use the help function, which will show you the docstring of the object (can be used on a module/function/class etc) if it has any.
For example if you want to know what the datetime.datetime.now does (I dont have mathplotlib install to use it on it):
>>> import datetime
>>> help(datetime.datetime.now)
Help on built-in function now:
now(tz=None) method of builtins.type instance
Returns new datetime object representing current time local to tz.
tz
Timezone object.
If no tz is specified, uses local timezone.
I'm going through a data visualisation in python course to help with my lab reports and I cant seem to understand the purpose of the second line in this example of creating a scatter plot:
import matplotlib.pyplot as plt
fig,ax = plt.subplots()
ax.scatter([1,2,3,4,5],[1,2,3,4,5])
ax.set_xlabel('X')
ax.set_ylabel('Y')
plt.show()
Can someone explain what that first line is doing here.
I have only started using python and I haven't seen this sort of syntax before(fig,ax = plt.subplots()). I tried to test if it was a way to assign 2 variables to the same thing by writing x,y=1, I ended up getting an error "int object is not iterable".
Another thing I dont understand is where is fig being used anywhere in the body of code? My current understanding is that the top line defined what fig and ax are, I can see that ax is used in the body of the code to define the scatter plot, but where is fig used? I tried to delete it and run the code, but I got this error:
'tuple' object has no attribute 'scatter'
If someone could please explain the above misconceptions.
As per the official docs, subplots creates a figure and a set of subplots. Specifically,
Returns:
fig : Figure
ax : axes.Axes object or array of Axes objects. ax can be either a single Axes object or an array of Axes objects if more than one subplot was created. The dimensions of the resulting array can be controlled with the squeeze keyword, see above.
Now when you do
fig, ax = plt.subplots()
the figure object is assigned to the variable fig and the axis object is assigned to the variable ax.
The fig will then give you access to the attributes on a figure-level, for instance, the figure title. The ax will give you access to the attributes on individual subplot level, such as the legends, axis-labels, ticks, of each individual subplot. It will be as array of Axes objects in case you have more than one subplot.
I tried to test if it was a way to assign 2 variables to the same thing by writing x,y=1, I ended up getting an error "int object is not iterable".
You are almost right. That is syntax to assign multiple variables at the same time, but what you are missing is that plt.subplots() returns a tuple - of two values paired together.
If you want to better understand it you can run:
a, b = (1, 4)
or
a,b = 1, 4
(it's the same as far as python is concerns, it packs/unpacks values to a tuple if multiple values are used or returned)
I tried to delete it and run the code, but I got this error:
'tuple' object has no attribute 'scatter'
This is also related to why you got this error. The figure is indeed not in use in your code snippet, but you need it for python to understand you want to use part of the tuple and not the tuple itself.
For example: a=(1,2) will result in a holding a tuple, but in a, b = 1, 2 each of the created variables will hold an integer.
In your case, the axis object has a method scatter, which the tuple object does not have, hence your error.
EDIT: The issue is most likely about the version. The levels argument takes an integer argument in version 3.0.0, while this issue has occurred while using version 2.2.2.
UPDATE: The issue didn't occur after installing the version >=3.0.0.
I'm trying to make a contour plot in Python using the matplotlib.pyplot.contourf() function, and it works perfectly like this:
plt.contourf(x, y, z)
but when I try to specify an integer for the levels argument, like this:
plt.contourf(x, y, z, levels=100)
it always returns the error: TypeError: len() of unsized object
In the documentation, it says that the argument levels can be either int or array_like so I don't know why it would even call the len() function
Any ideas why this happens and any suggestion on how to fix it?
Sorry, this happens to you. The documentation changed in version 2.2.3 without this feature being fully implemented. So depending on the version of matplotlib the levels argument is interpreted differently.
matplotlib < 3.0.0
levels is interpreted as a list of levels where to draw contours. An integer is interpreted as a single level. For a contourf (a filled contour) plot you need at least two levels. Use the previously known way to specfify the number of levels as the second or fourth unnamed argument
plt.contourf(z, 100)
plt.contourf(x, y, z, 100)
matplotlib >= 3.0.0
levels can take either a list or an integer. When an integer, it signifies the (approximate [*]) number of levels. The relevant PR is this.
plt.contourf(z, levels=100)
plt.contourf(x, y, z, levels=100)
I am using Matplotlib to plot a 3*4 subplots. I am going to change the style of tick label to 'sci' so that the plotting can be more neat. But using the following code, the ticklabel_format do not even take effect on the axis.
import matplotlib.pylab as pl
fig, axes = pl.subplots(nrows=3, ncols=4)
for i,row in enumerate(axes):
for j,ax in enumerate(row):
ax.set_title('title')
ax.ticklabel_format(styl='plain')
pl.tight_layout()
pl.show()
I have intently make a typo 'styl', but it doesn't report error. So I assume the ticklabel_format function doesn't even run.
It not taking effect because ax.ticklabel_format takes any keyword argument and creates a dictionary. To see this take a look at the documentation here and you will see it takes an argument **kwargs. If you just replace styl with style then your code will work.
I suggest you take a look at this SO post to get a feel of what was going wrong but in brief: the function can take any argument. It then attempts to pass these on to other functions. If none of these require it then the argument is simply lost in the ether. As a result there is no error message!
Try playing around with the following example to get a feel **kwargs.
def f(**kwargs):
print kwargs
return
f(anything='something')