I'm trying to plot text values instead of symbols (for an MDS solution), and matplotlib.pyplot is giving me errors I don't understand. I've updated ipython and matplotlib to make sure it's not an old problem (or a problem with old versions), and I haven't been able to find any answers or reports of similar problems here (or elsewhere via google).
So, for example, after invoking ipython --pylab, if I type:
x = random.rand(4)
y = random.rand(4)
s = [str(i) for i in arange(4)+1]
text(x,y,s)
I get this error:
Traceback (most recent call last):
File "//anaconda/lib/python2.7/site-packages/matplotlib/artist.py", line 55, in
draw_wrapper draw(artist, renderer, *args, **kwargs)
File "//anaconda/lib/python2.7/site-packages/matplotlib/figure.py", line 1034, in draw
func(*args)
File "//anaconda/lib/python2.7/site-packages/matplotlib/artist.py", line 55, in
draw_wrapper draw(artist, renderer, *args, **kwargs)
File "//anaconda/lib/python2.7/site-packages/matplotlib/axes.py", line 2086, in draw
a.draw(renderer)
File "//anaconda/lib/python2.7/site-packages/matplotlib/artist.py", line 55, in
draw_wrapper draw(artist, renderer, *args, **kwargs)
File "//anaconda/lib/python2.7/site-packages/matplotlib/text.py", line 547, in draw
bbox, info, descent = self._get_layout(renderer)
File "//anaconda/lib/python2.7/site-packages/matplotlib/text.py", line 287, in
_get_layout key = self.get_prop_tup()
File "//anaconda/lib/python2.7/site-packages/matplotlib/text.py", line 696, in
get_prop_tup x, y = self.get_position()
File "//anaconda/lib/python2.7/site-packages/matplotlib/text.py", line 684, in
get_position x = float(self.convert_xunits(self._x))
TypeError: only length-1 arrays can be converted to Python scalars
I get the same error if I try calling text with scalars rather than vectors/lists (e.g., text(x[0],y[0],s[0]), or any number of variants of the arguments to the text function). The same thing happens:
with figtext,
if I manually import matplotlib.pyplot as plt and call plt.text, and
if I explicitly make figure and subplot objects and/or call scatter(x,y) first.
Also, for what it's worth, once this problem occurs, the error message appears again if I manually resize the figure. Possibly related is the fact that changes to figures don't update automatically, but only after I plot in another subplot or manually resize the figure. But I digress.
I've got an updated installation of Anaconda on a Mac (with Mavericks), and, as mentioned above, I'm using iPython.
plt.text expects a single x, y, and string values, not sequences. (See: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.text )
Just use a loop.
For example:
import numpy as np
import matplotlib.pyplot as plt
x, y = np.random.rand(2,4)
s = [str(i) for i in np.arange(1, 5)]
fig, ax = plt.subplots()
text = [ax.text(*item) for item in zip(x, y, s)]
plt.show()
Related
When trying to run this little piece of code inspired from the matplotlib documentation Blend transparency with color in 2-D images:
import numpy as np
import matplotlib.pyplot as plt
test = np.random.random((300, 300))
plt.figure()
plt.imshow(test, alpha = test/test.max())
plt.show()
I end up with :
<matplotlib.image.AxesImage at 0x7f8bfe8cc610>Traceback (most recent call last):
File "/Users/darkvador/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_qt5.py", line 508, in _draw_idle
self.draw()
File "/Users/darkvador/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_agg.py", line 388, in draw
self.figure.draw(self.renderer)
File "/Users/darkvador/opt/anaconda3/lib/python3.7/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/Users/darkvador/opt/anaconda3/lib/python3.7/site-packages/matplotlib/figure.py", line 1709, in draw
renderer, self, artists, self.suppressComposite)
File "/Users/darkvador/opt/anaconda3/lib/python3.7/site-packages/matplotlib/image.py", line 135, in _draw_list_compositing_images
a.draw(renderer)
File "/Users/darkvador/opt/anaconda3/lib/python3.7/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/Users/darkvador/opt/anaconda3/lib/python3.7/site-packages/matplotlib/axes/_base.py", line 2647, in draw
mimage._draw_list_compositing_images(renderer, self, artists)
File "/Users/darkvador/opt/anaconda3/lib/python3.7/site-packages/matplotlib/image.py", line 135, in _draw_list_compositing_images
a.draw(renderer)
File "/Users/darkvador/opt/anaconda3/lib/python3.7/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/Users/darkvador/opt/anaconda3/lib/python3.7/site-packages/matplotlib/image.py", line 619, in draw
renderer, renderer.get_image_magnification())
File "/Users/darkvador/opt/anaconda3/lib/python3.7/site-packages/matplotlib/image.py", line 881, in make_image
unsampled=unsampled)
File "/Users/darkvador/opt/anaconda3/lib/python3.7/site-packages/matplotlib/image.py", line 530, in _make_image
np.asarray(alpha_channel, np.float32) * out_alpha * alpha,
ValueError: operands could not be broadcast together with shapes (740,740) (300,300)
I'm under macos-catalina, with python:
Python 3.7.7 (default, Mar 26 2020, 10:32:53)
[Clang 4.0.1 (tags/RELEASE_401/final)] :: Anaconda, Inc. on darwin
Note that the error does not occur if:
I comment the plt.show()
I use a constant alpha-value
I run this piece of code under a classic python 3.6 from the linux distribution
From the matplotlib 3.1.3 documentation, the alpha keyword argument must be a scalar value.
You should update to Matplotlib 3.3.1, because giving an array for the alpha parameters must have been implemented in between these two versions.
Your alpha array alpha/alpha.max() does not match the shape of the actual image array test. From the test code you provided, we can create an alpha array and successfully display it as an alpha-varying image with the code below. So you have to make sure the alpha array has the exact same shape as the test array.
import numpy as np
import matplotlib.pyplot as plt
test = np.random.random((300, 300))
alpha = test / test.max()
print(alpha)
plt.figure()
plt.imshow(test, alpha = alpha)
plt.show()
producing the image below.
I'm trying to plot a function that gives the arctan of the angle of several scatterplots (it's a physics experiment):
Here is my code:
import numpy as np
import matplotlib.pyplot as plt
filename='rawPhaseDataf2f_17h_15m.dat'
datatype=np.dtype( [('Shotnumber',np.dtype('>f8')),('A1',np.dtype('>f8')), ('A2',np.dtype('>f8')), ('f2f',np.dtype('>f8')), ('intensity',np.dtype('>f8'))])
data=np.fromfile(filename,dtype=datatype)
#time=data['Shotnumber']/9900 # reprate is 9900 Hz -> time in seconds
A1=data['A1']
A2=data['A2']
#np.sort()
i=range(1,209773)
def x(i) :
return arctan((A1.item(i)/A2.item(i))*(i/209772))
def y(i) :
return i*2*pi/209772
plot(x,y)
plt.figure('Scatterplot')
plt.plot(A1,A2,',') #Scatterplot
plt.xlabel('A1')
plt.ylabel('A2')
plt.figure('2D Histogram')
plt.hist2d(A1,A2,100) # 2D Histogram
plt.xlabel('A1')
plt.ylabel('A2')
plt.show()
My error is:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/spyderlib/widgets/externalshell /sitecustomize.py", line 540, in runfile
execfile(filename, namespace)
File "/home/nelly/Bureau/ Téléchargements/Kr4 Experiment/read_rawPhaseData.py", line 21, in <module>
plot(x,y)
File "/usr/lib/pymodules/python2.7/matplotlib/pyplot.py", line 2987, in plot
ret = ax.plot(*args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 4138, in plot
self.add_line(line)
File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 1497, in add_line
self._update_line_limits(line)
File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 1508, in _update_line_limits
path = line.get_path()
File "/usr/lib/pymodules/python2.7/matplotlib/lines.py", line 743, in get_path
self.recache()
File "/usr/lib/pymodules/python2.7/matplotlib/lines.py", line 420, in recache
x = np.asarray(xconv, np.float_)
File "/usr/lib/python2.7/dist-packages/numpy/core/numeric.py", line 460, in asarray
return array(a, dtype, copy=False, order=order)
TypeError: float() argument must be a string or a number
I know that the problem is from the plot(x,y). I think that my error comes from the definition of x and y. A1 and A2 are matrix, N the number of points and Ak is the index of the matrix. I want to have arctan(A1k/A2k)*(k/N).
There are lots of problems with your code, and your understanding of python and array operations. I'm just going to handle the first part of the code (and the error you get), and hopefully you can continue to fix it from there.
This should fix the error you're getting and generate a plot:
# size = 209772
size = A1.size # I'm assuming that the size of the array is 209772
z = np.arange(1, size+1)/(size+1) # construct an array from [1/209773, 1.0]
# Calculate the x and y arrays
x = np.arctan((A1/A2)*z)
y = z*2*pi
# Plot x and y
plt.plot(x, y)
Discussion:
There are lots of issues with this chunk of code:
i=range(1,209773)
def x(i) :
return arctan((A1.item(i)/A2.item(i))*(i/209772))
def y(i) :
return i*2*pi/209772
plot(x, y)
You're defining two functions called x and y, and then you are passing those functions to the plotting method. The plotting method accepts numbers (in lists or arrays), not functions. That is the reason for the error that you are getting. So you instead need to construct a list/array of numbers and pass that to the function.
You're defining a variable i which is a list of numbers. But when you define the functions x and y, you are creating new variables named i which have nothing to do with the list you created earlier. This is because of how "scope" works in python.
The functions arctan and plot are not defined "globally", instead they are only defined in the packages numpy and matplotlib. So you need to call them from those packages.
The following example returns an error. It appears that using a discrete (not continuous) scale for the x-axis in ggplot in Python is not supported?
import pandas as pd
import ggplot
df = pd.DataFrame.from_dict({'a':['a','b','c'],
'percentage':[.1,.2,.3]})
p = ggplot.ggplot(data=df,
aesthetics=ggplot.aes(x='a',
y='percentage'))\
+ ggplot.geom_point()
print(p)
As mentioned, this returns:
Traceback (most recent call last):
File "/Users/me/Library/Preferences/PyCharm2016.1/scratches/scratch_1.py", line 30, in <module>
print(p)
File "/Users/me/lib/python3.5/site-packages/ggplot/ggplot.py", line 116, in __repr__
self.make()
File "/Users/me/lib/python3.5/site-packages/ggplot/ggplot.py", line 627, in make
layer.plot(ax, facetgroup, self._aes, **kwargs)
File "/Users/me/lib/python3.5/site-packages/ggplot/geoms/geom_point.py", line 60, in plot
ax.scatter(x, y, **params)
File "/Users/me/lib/python3.5/site-packages/matplotlib/__init__.py", line 1819, in inner
return func(ax, *args, **kwargs)
File "/Users/me/lib/python3.5/site-packages/matplotlib/axes/_axes.py", line 3838, in scatter
x, y, s, c = cbook.delete_masked_points(x, y, s, c)
File "/Users/me/lib/python3.5/site-packages/matplotlib/cbook.py", line 1848, in delete_masked_points
raise ValueError("First argument must be a sequence")
ValueError: First argument must be a sequence
Any workarounds for using ggplot with scatters on a discrete scale?
One option is to generate a continuous series, and use the original variable as labels. But this seems like a painful workaround.
df = pd.DataFrame.from_dict( {'a':[0,1,2],
'a_name':['a','b','c'],
'percentage':[.1,.2,.3]})
p = ggplot.ggplot(data=df,
aesthetics=ggplot.aes(x='a',
y='percentage'))\
+ ggplot.geom_point()\
+ ggplot.scale_x_continuous(breaks=list(df['a']),
labels=list(df['a_name']))
I was getting the same error when trying to plot 2 columns of a dataframe. I was reading the data from a csv file and converting it into a dataframe.
readdata=csv.reader(open(filename),delimiter="\t")
df= pd.DataFrame(data, columns=header)
df.columns=["pulseVoltage","dutVoltage","dutCurrent","leakageCurrent"]
print (df.dtypes)
When I checked the data types, for some reason they were shown as object instead of float that I expected (I am a newbie and this might be trivial knowledge which I don't know). Therefore, I went ahead and did an explicit conversion of columns to data type float.
df["dutVoltage"]=df["dutVoltage"].astype("float")
df["dutCurrent"]=df["dutCurrent"].astype("float")
Now I can use ggplot to plot the data without any error.
print ggplot(df, aes('dutVoltage','dutCurrent'))+ \
geom_point()
I'm a novice programmer and my hunch is that this error is due to some sort of installation or version problem, but I have no idea what. I'm running python 2.7 on OS 10.8, and just installed numpy 1.12.0 and matplotlib-1.5.1 today in an attempt to construct a heatmap.
I'm trying to run this example from the matplotlib site (http://matplotlib.org/examples/api/image_zcoord.html):
"""
Show how to modify the coordinate formatter to report the image "z"
value of the nearest pixel given x and y
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
X = 10*np.random.rand(5, 3)
fig, ax = plt.subplots()
ax.imshow(X, cmap=cm.jet, interpolation='nearest')
numrows, numcols = X.shape
def format_coord(x, y):
col = int(x + 0.5)
row = int(y + 0.5)
if col >= 0 and col < numcols and row >= 0 and row < numrows:
z = X[row, col]
return 'x=%1.4f, y=%1.4f, z=%1.4f' % (x, y, z)
else:
return 'x=%1.4f, y=%1.4f' % (x, y)
ax.format_coord = format_coord
plt.show()
A plot window appears, but nothing is displayed, and the mouseover coordinates kind of "stack" instead of refreshing and quickly become illegible. I also get this error in terminal:
AttributeError: 'numpy.ndarray' object has no attribute 'as_rgba_str'
Other, similar examples from the matplotlib site also exhibit similar behavior.
Of course, please let me know if this is a duplicate (I tried to search for an answer but didn't find anything similar to my problem, but I also might just not know what to search for).
If it is an installation error, instructions on how to fix it or a point in the right direction with detailed instructions would be much appreciated. Thank you!
Edit: Here's the traceback before the error:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/matplotlib-1.5.1+1539.g1111c1d- py2.7-macosx-10.8-x86_64.egg/matplotlib/artist.py", line 63, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/matplotlib-1.5.1+1539.g1111c1d-py2.7-macosx-10.8-x86_64.egg/matplotlib/figure.py", line 1262, in draw
renderer, self, dsu, self.suppressComposite)
File "/usr/local/lib/python2.7/site-packages/matplotlib-1.5.1+1539.g1111c1d-py2.7-macosx-10.8-x86_64.egg/matplotlib/image.py", line 139, in _draw_list_compositing_images
a.draw(renderer)
File "/usr/local/lib/python2.7/site-packages/matplotlib-1.5.1+1539.g1111c1d-py2.7-macosx-10.8-x86_64.egg/matplotlib/artist.py", line 63, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/matplotlib-1.5.1+1539.g1111c1d-py2.7-macosx-10.8-x86_64.egg/matplotlib/axes/_base.py", line 2355, in draw
mimage._draw_list_compositing_images(renderer, self, dsu)
File "/usr/local/lib/python2.7/site-packages/matplotlib-1.5.1+1539.g1111c1d-py2.7-macosx-10.8-x86_64.egg/matplotlib/image.py", line 139, in _draw_list_compositing_images
a.draw(renderer)
File "/usr/local/lib/python2.7/site-packages/matplotlib-1.5.1+1539.g1111c1d-py2.7-macosx-10.8-x86_64.egg/matplotlib/artist.py", line 63, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/matplotlib-1.5.1+1539.g1111c1d-py2.7-macosx-10.8-x86_64.egg/matplotlib/image.py", line 472, in draw
renderer.draw_image(gc, l, b, im)
File "/usr/local/lib/python2.7/site-packages/matplotlib-1.5.1+1539.g1111c1d-py2.7-macosx-10.8-x86_64.egg/matplotlib/backends/backend_macosx.py", line 113, in draw_image
nrows, ncols, data = im.as_rgba_str()
AttributeError: 'numpy.ndarray' object has no attribute 'as_rgba_str'
Definitely some sort of install error, I installed Anaconda and the problem was fixed. For those who find this question in the future, ActivePython does not have numpy or scipy.
I cant fix your problem but I can tell you its an installation problem, the code you posted worked perfect on my install using python 2.7. though I am using windows instead of IOS
For a subplot (self.intensity), I want to shade the area under the graph.
I tried this, hoping it was the correct syntax:
self.intensity.fill_between(arange(l,r), 0, projection)
Which I intend as to do shading for projection numpy array within (l,r) integer limits.
But it gives me an error. How do I do it correctly?
Heres the traceback:
Traceback (most recent call last):
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_wx.py", line 1289, in _onLeftButtonDown
FigureCanvasBase.button_press_event(self, x, y, 1, guiEvent=evt)
File "/usr/lib/pymodules/python2.7/matplotlib/backend_bases.py", line 1576, in button_press_event
self.callbacks.process(s, mouseevent)
File "/usr/lib/pymodules/python2.7/matplotlib/cbook.py", line 265, in process
proxy(*args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/cbook.py", line 191, in __call__
return mtd(*args, **kwargs)
File "/root/dev/spectrum/spectrum/plot_handler.py", line 55, in _onclick
self._call_click_callback(event.xdata)
File "/root/dev/spectrum/spectrum/plot_handler.py", line 66, in _call_click_callback
self.__click_callback(data)
File "/root/dev/spectrum/spectrum/plot_handler.py", line 186, in _on_plot_click
band_data = self._band_data)
File "/root/dev/spectrum/spectrum/plot_handler.py", line 95, in draw
self.intensity.fill_between(arange(l,r), 0, projection)
File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 6457, in fill_between
raise ValueError("Argument dimensions are incompatible")
ValueError: Argument dimensions are incompatible
It seems like you are trying to fill the part of the projection from l to r. fill_between expects the x and y arrays to be of equal lengths, so you can not expect to fill part of the curve only.
To get what you want, you can do either of the following:
1. send only part of the projection that needs to be filled to the command; and draw the rest of the projection separately.
2. send a separate boolean array as argument that defines the sections to fill in. See the documentation!
For the former method, see the example code below:
from pylab import *
a = subplot(111)
t = arange(1, 100)/50.
projection = sin(2*pi*t)
# Draw the original curve
a.plot(t, projection)
# Define areas to fill in
l, r = 10, 50
# Fill the areas
a.fill_between(t[l:r], projection[l:r])
show()