(matpolotlib) ValueError: too many values to unpack - python

I am getting the following error when trying to display data values instead of markers:
Complete Traceback:
Traceback (most recent call last):
File "plotpoints.py", line 45, in <module>
plt.annotate(grid_x,grid_y)
File "/usr/lib/pymodules/python2.7/matplotlib/pyplot.py", line 3405, in annotate
ret = gca().annotate(*args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 3404, in annotate
a = mtext.Annotation(*args, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/text.py", line 1813, in __init__
annotation_clip=annotation_clip)
File "/usr/lib/pymodules/python2.7/matplotlib/text.py", line 1442, in __init__
x, y = self.xytext = xytext
ValueError: too many values to unpack
Code:
m = mapformat()
dx = 0.25
grid_x, grid_y = np.mgrid[-85:64:dx, 34:49:dx]
grid_z = griddata((data[:,1],data[:,0]), data[:,2], (grid_x,grid_y), method='linear')
x,y = m(data[:,1], data[:,0]) # flip lat/lon
grid_x,grid_y = m(grid_x,grid_y)
plt.annotate(grid_x,grid_y)
#m.plot(grid_x,grid_y, 'ko', markersize=2)
What am I doing wrong?

I don't think you are calling annotate correctly
plt.annotate(grid_x,grid_y)
That looks like 2 arrays or lists of points (I haven't fully deduced how you define those 2 variables).
But the documentation is:
ax.annotate('local max', xy=(3, 1), ...)
The 1st argument is the text and the second a tuple with the coordinates.
I'm guessing that the calling sequence converts your xgrid argument to mtext, and ygrid to its xytext
x, y = self.xytext = xytext
If there are more than 2 values in ygrid, this unpacking will produce your error.
annotate adds text at a specific point on the plot; it can't be used to label the coordinates of a bunch of data points (at least not in one call).

One of the functions that you're calling on the right is returning more values than there are variables to assign to on the left.
For example, if you do the following in a REPL:
a,b = [1,2,3]
You'll get the following error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack
It'll help to see which line the code is failing at - this way, you'll know which function is returning too many variables.

Related

Python Plotting Combine 2 Plots

I am trying to plot streamlines in matplotlib over a contour plot by combining these two plots shown below but showing my code first:
ax = plt.axes(projection=ccrs.PlateCarree())
ax.coastlines(lw=1)
clevs = np.linspace(-3., 3., 13)
cnplot = plt.contourf(lon,lat,anomspeed,clevs,add_labels=True,cmap='jet')
cbar = plt.colorbar(cnplot)
cbar.set_label('Standard Deviations')
plt.title('~50m Wind Speed Anomaly {} 2020'.format(calendar.month_name[currm-1]))
diffu = (uwndc - uwnd); diffv = (vwndc - vwnd)
lonn, latt = np.meshgrid(lon, lat)
plt.streamplot(lonn[0,:], latt[:,0], diffu, diffv, density=(3.5,3.5),
color='k',linewidth=0.4,arrowsize=0.6)#x,y 1D and u,v are 2D
I am getting this error (full traceback shown) when i try and run the code shown below but I do not understand 'ravel' error. I suppose it has something to do with matching coordinates or related between the two plots..? thank you for any help!
Traceback (most recent call last):
File "C:\Users\U321103\.spyder-
py3\MonthlyReport_mapsNCEP_contour_monthly_wspdv2.py", line 85, in <module>
plt.streamplot(lonn[0,:], latt[:,0], diffu, diffv, density=(3.5,3.5),
color='k',linewidth=0.4,arrowsize=0.6)
File "C:\Users\U321103\AppData\Local\Continuum\anaconda3\envs\Maps\lib\site-
packages\matplotlib\pyplot.py", line 2906, in streamplot
if data is not None else {}))
File "C:\Users\U321103\AppData\Local\Continuum\anaconda3\envs\Maps\lib\site-
packages\cartopy\mpl\geoaxes.py", line 1897, in streamplot
target_extent=target_extent)
File "C:\Users\U321103\AppData\Local\Continuum\anaconda3\envs\Maps\lib\site-
packages\cartopy\vector_transform.py", line 146, in vector_scalar_to_grid
return _interpolate_to_grid(nx, ny, x, y, u, v, *scalars, **kwargs)
File "C:\Users\U321103\AppData\Local\Continuum\anaconda3\envs\Maps\lib\site-
packages\cartopy\vector_transform.py", line 67, in _interpolate_to_grid
s_grid_tuple += (griddata(points, s.ravel(), (x_grid, y_grid),
AttributeError: 'Variable' object has no attribute 'ravel'
I'm looking to solving this same problem and I found an answer to a similar question that help me plotting streamlines and contour togheter. Take a look at here.
In a nutshell, instead of:
plt.streamplot(lonn[0,:], latt[:,0], diffu, diffv, density=(3.5,3.5), color='k',linewidth=0.4,arrowsize=0.6)
You'd use
plt.streamplot(lonn[0,:], latt[:,0], np.array(diffu), np.array(diffv), density=(3.5,3.5), color='k',linewidth=0.4,arrowsize=0.6)
The use of np.array() solves the problem for me.
Best regards,
Mateus

Invalid literal for float when plotting data read from a file, and a floating point division error

I've got a script that takes the output of a separate C++ executable and creates a scatter plot/bifurcation diagram of the resulting data. The application context is to look at angle values versus the driving force by iterating through multiple values of a driving force to get the resulting angle and stroboscopically sampling the results, as a problem regarding a nonlinearly damped driven pendulum from a course on computational physics
import os
import sys
import numpy as np
import matplotlib.pyplot as plt
gbl = 1.0
kappa = 0.5
T_D = 9.424778
ic_ang = 0.1
ic_avel = 0.0
t_final = 200
Nstep = 7500
method = "runge_kutta"
ic_ang = 0.1
Fmin = 0.8
Fmax = 1.6
F_D = float(Fmin)
tstep = T_D/(t_final/Nstep)
Nrep = 3 * tstep
select =[]
step = 0.01
Nite = (Fmax-Fmin)/step
rng = int(Nite-1)
for i in range(rng):
pfile= open('param.dat','w')
pfile.write('%f %f %f %f\n' %(gbl,kappa,F_D,T_D))
pfile.write('%f %f %f\n'%(ic_ang,ic_avel,t_final))
pfile.write('%d %s\n'%(Nstep,method))
pfile.close()
os.system('./a.out > bif.log')
with open("data.out",'r') as datafile:
data=datafile.readlines()
select=data[-Nrep:Nstep:int(tstep)]
for j in select:
plt.plot(F_D, j, "o", color='b', markersize=0.3)
print(F_D,j)
F_D += step
plt.xlabel(r'$F_D$')
plt.ylabel(r'$\theta_{repeat}$')
#plt.xticks([])
plt.yticks([])
plt.show()
However, when I try to run the script I get
Traceback (most recent call last):
File "bif.py", line 45, in <module>
plt.plot(F_D, j, "o", color='b',markersize=0.3)
File"/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/pyt hon/matplotlib/pyplot.py", line 2987, in plot
ret = ax.plot(*args, **kwargs)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/matplotlib/axes.py", line 4138, in plot
self.add_line(line)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/matplotlib/axes.py", line 1497, in add_line
self._update_line_limits(line)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/matplotlib/axes.py", line 1508, in
_update_line_limits
path = line.get_path()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/matplotlib/lines.py", line 743, in get_path
self.recache()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/matplotlib/lines.py", line 429, in recache
y = np.asarray(yconv, np.float_)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/numpy/core/numeric.py", line 460, in asarray
return array(a, dtype, copy=False, order=order)
ValueError: invalid literal for float(): 0 0.1 0 0.004995834722
Modifying some of the values to try and debug the script raises a separate exception
Traceback (most recent call last):
File "bif.py", line 24, in <module>
tstep = T_D/(t_final/Nstep)
ZeroDivisionError: float division by zero
I am extremely new to Python so neither one of these exceptions makes much sense to me. However, as Nstep, t_final, and T_D all have finite values, there is no reason (that I can see anyhow) for a dividing by zero error.
I see possible errors for the ValueError as well, as the output in the 1st and 3rd columns (time and angular velocity) aren't float values as they should be. I don't, however, know why these values aren't being converted to a float as they should be.
Any help would be very much appreciated.
EDIT:THIS ISSUE HAS BEEN SOLVED
I think you're asking two questions here, and as I can see the last one about division by zero is the easier one. Namely, the expression t_final/Nstep, as it stands now in your code, is an integer division expression, and the result is 0. Thus the line
tstep = T_D/(t_final/Nstep)
divides by zero.
The second question is why matplotlib complains about the data. To really diagnose this problem we need to look at the content of the data file read by your program. However, I think the problem stems from your attempt to pass text (Python string) to a function expecting numeric data type. When you readlines() the input file, I don't think you're doing any conversion. As a result, a slice of text string is passed to plt.plot and matplotlib struggled to construct a numeric data type from this representation. It would be much better if you read the data, do the proper conversion according to the file format and the logic of your analysis. You may want to look into numpy.loadtxt if it's the case that you're dealing with a text data file.

Python Matplotlib Streamplot providing start points

I am trying to add start points to a streamline plot. I found an example code using start points here; at this link a different issue is discussed but the start_points argument works. From here I grabbed the streamline example code (images_contours_and_fields example code: streamplot_demo_features.py). I don't understand why I can define start points in one code and not the other. I get the following error when I try to define start points in the example code (streamplot_demo_features.py):
Traceback (most recent call last):
File "<ipython-input-79-981cad64cff6>", line 1, in <module>
runfile('C:/Users/Admin/.spyder/StreamlineExample.py', wdir='C:/Users/Admin/.spyder')
File "C:\ProgramData\Anaconda2\lib\site-packages\spyder\utils\site\sitecustomize.py", line 866, in runfile
execfile(filename, namespace)
File "C:\ProgramData\Anaconda2\lib\site-packages\spyder\utils\site\sitecustomize.py", line 87, in execfile
exec(compile(scripttext, filename, 'exec'), glob, loc)
File "C:/Users/Admin/.spyder/StreamlineExample.py", line 28, in <module>
ax1.streamplot(X, Y, U, V,start_points=start_points)
File "C:\ProgramData\Anaconda2\lib\site-packages\matplotlib\__init__.py", line 1891, in inner
return func(ax, *args, **kwargs)
File "C:\ProgramData\Anaconda2\lib\site-packages\matplotlib\axes\_axes.py", line 4620, in streamplot
zorder=zorder)
File "C:\ProgramData\Anaconda2\lib\site-packages\matplotlib\streamplot.py", line 144, in streamplot
sp2[:, 0] += np.abs(x[0])
ValueError: non-broadcastable output operand with shape (1,) doesn't match the broadcast shape (100,)
I've notice there isn't much on the web in way of using start_points, so any additional information would be helpful.
The main difference between the example that successfully uses start_points and the example from the matplotlib page is that the first uses 1D arrays as x and y grid, whereas the official example uses 2D arrays.
Since the documentation explicitely states
x, y : 1d arrays, an evenly spaced grid.
we might stick to 1D arrays. It's unclear why the example contradicts the docsting, but we can simply ignore that.
Now, using 1D arrays as grid, start_points works as expected in that it takes a 2-column array (first column x-coords, second y-coords).
A complete example:
import numpy as np
import matplotlib.pyplot as plt
x,y = np.linspace(-3,3,100),np.linspace(-3,3,100)
X,Y = np.meshgrid(x,y)
U = -1 - X**2 + Y
V = 1 + X - Y**2
speed = np.sqrt(U*U + V*V)
start = [[0,0], [1,2]]
fig0, ax0 = plt.subplots()
strm = ax0.streamplot(x,y, U, V, color=(.75,.90,.93))
strmS = ax0.streamplot(x,y, U, V, start_points=start, color="crimson", linewidth=2)
plt.show()

Plotting asymmetric error bars for a single point using errorbar

Goal: To plot asymmetric x error bars for a single point using errorbar. I want to display the inter quartile range (IQR) for a data set.
Code:
import numpy as np
import matplotlib.pyplot as plt
y = 1.0
data = np.random.rand(100)
median = np.median(data)
upper_quartile = np.percentile(data, 75)
lower_quartile = np.percentile(data, 25)
IQR = upper_quartile - lower_quartile
plt.errorbar(median, y, xerr=[lower_quartile ,upper_quartile], fmt='k--')
plt.savefig('IQR.eps')
plt.show()
Error:
Traceback (most recent call last):
File "IQR.py", line 15, in <module>
plt.errorbar(median, y, xerr=[0.5,0.75], fmt='k--')
File "/usr/lib/pymodules/python2.7/matplotlib/pyplot.py", line 2251, in errorbar
ret = ax.errorbar(x, y, yerr, xerr, fmt, ecolor, elinewidth, capsize, barsabove, lolims, uplims, xlolims, xuplims, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 5327, in errorbar
in cbook.safezip(x,xerr)]
File "/usr/lib/pymodules/python2.7/matplotlib/cbook.py", line 1294, in safezip
raise ValueError(_safezip_msg % (Nx, i+1, len(arg)))
ValueError: In safezip, len(args[0])=1 but len(args[1])=2
My issue is that I am unable to create asymmetric error bars for a single point, where the point will represent the mean and the upper and lower limits of the error bars will be the upper and lower quartile.
I typically use vlines or hlines for this (I think the caps are just distracting):
plt.hlines( y, median-lower_quartile, median+upper_quartile)
plt.plot(median, y, 'o')
If you still want to use errorbar, you can try
plt.errorbar(median, y, xerr=np.array([[lower_quartile ,upper_quartile]]).T,
fmt='ko')
Note that I don't really know how you define your quartiles here, so you may need to make sure you get the right numbers in!!!
Make sure xerr gets a list of lists. If it's only one list, it'll assume it contains symmetrical error bars for two Y's. But there's only one Y, which is why you get the error.
Also your errorbars are wrong. Change the errorbar call to
plt.errorbar(median, y, xerr=[[median-lower_quartile ,upper_quartile-median]], fmt='k--')
The two arguments you're passing to safezip are of different sizes. The stacktrace you posted says so right here:
ValueError: In safezip, len(args[0])=1 but len(args[1])=2
What that's saying is argument one's length is 1 but argument two's length is 2, so zip can't actually combine those two lists.

subtracting arrays in numpy and plotting with pylab

I have a simple text file composed of 8 columns and I read it with loadtxt function. I want to plot as x-axis column6-column7 and as y-axis column7-column8 so I put this command
>>> pl.plot(np.subtract(data2[:,6], data2[:7]), np.subtract(data2[:,7], data2[:,8]))
and it gave this error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (59427) (7,9)
What is the problem? and how to do that?
data2[:7] should be data2[:,7] -- you missed a comma.
data2[:7] apparently has shape (7,9), while data2[:,6] has shape (50427,). The error message is saying that the two arrays can not be broadcasted to a common shape upon which np.subtract can be applied.
x = data2[:,6] - data2[:,7]
y = data2[:,7] - data2[:,8]
pl.plot(x, y)

Categories

Resources