Skip to content
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

2d array vs 1d array inconsistency with optional argument to Plot3D #58

Open
ghost opened this issue May 30, 2014 · 3 comments
Open

2d array vs 1d array inconsistency with optional argument to Plot3D #58

ghost opened this issue May 30, 2014 · 3 comments

Comments

@ghost
Copy link

ghost commented May 30, 2014

The problem is based on the way that julia distinguishes between singleton arrays and nx1 two-dimensional arrays. The optional argument zs for plot3D( xs, ys, zs=zs ) is not robust to these two different representations but the first two arguments xs, ys are.

Say a matrix of data is generated and three sets of points for plotting are extracted from the columns of the matrix:

mat = [ 1 4 7;2 5 8;3 6 9 ]
x = mat[ :,1 ]
y = mat[ :,2 ]
z = mat[ :,3 ]

Each vector x, y, z is a 3-element Array{Int64,1}. These can be plotted using:

using PyPlot
close( gcf() )
plot3D( x, y, zs=z )
display( gcf() )

However, say the matrix is transposed and the rows are spliced and transposed:

x = mat'[ 1,: ]'
y = mat'[ 2,: ]'
z = mat'[ 3,: ]'

Each vector is now a 3x1 Array{Int64,2} and plotting as above gives:

using PyPlot
close( gcf() )
plot3D( x, y, zs=z )
display( gcf() )
PyError (PyObject_Call) <type 'exceptions.ValueError'>
ValueError('could not broadcast input array from shape (3,1) into shape (3)',)
  File "/Library/Python/2.7/site-packages/matplotlib-1.4.x-py2.7-macosx-10.9-intel.egg/matplotlib/backend_bases.py", line 2177, in print_figure
    **kwargs)
  File "/Library/Python/2.7/site-packages/matplotlib-1.4.x-py2.7-macosx-10.9-intel.egg/matplotlib/backends/backend_agg.py", line 509, in print_png
    FigureCanvasAgg.draw(self)
  File "/Library/Python/2.7/site-packages/matplotlib-1.4.x-py2.7-macosx-10.9-intel.egg/matplotlib/backends/backend_agg.py", line 455, in draw
    self.figure.draw(self.renderer)
  File "/Library/Python/2.7/site-packages/matplotlib-1.4.x-py2.7-macosx-10.9-intel.egg/matplotlib/artist.py", line 59, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/Library/Python/2.7/site-packages/matplotlib-1.4.x-py2.7-macosx-10.9-intel.egg/matplotlib/figure.py", line 1050, in draw
    func(*args)
  File "/Library/Python/2.7/site-packages/matplotlib-1.4.x-py2.7-macosx-10.9-intel.egg/mpl_toolkits/mplot3d/axes3d.py", line 275, in draw
    Axes.draw(self, renderer)
  File "/Library/Python/2.7/site-packages/matplotlib-1.4.x-py2.7-macosx-10.9-intel.egg/matplotlib/artist.py", line 59, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/Library/Python/2.7/site-packages/matplotlib-1.4.x-py2.7-macosx-10.9-intel.egg/matplotlib/axes/_base.py", line 2076, in draw
    a.draw(renderer)
  File "/Library/Python/2.7/site-packages/matplotlib-1.4.x-py2.7-macosx-10.9-intel.egg/mpl_toolkits/mplot3d/art3d.py", line 124, in draw
    xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M)
  File "/Library/Python/2.7/site-packages/matplotlib-1.4.x-py2.7-macosx-10.9-intel.egg/mpl_toolkits/mplot3d/proj3d.py", line 198, in proj_transform
    vec = vec_pad_ones(xs, ys, zs)
  File "/Library/Python/2.7/site-packages/matplotlib-1.4.x-py2.7-macosx-10.9-intel.egg/mpl_toolkits/mplot3d/proj3d.py", line 187, in vec_pad_ones
    vec = np.array([xs,ys,zs,np.ones(xs.shape)])

while loading In[16], in expression starting on line 4
 in pyerr_check at /Users/user/.julia/v0.3/PyCall/src/exception.jl:58
 in pycall at /Users/user/.julia/v0.3/PyCall/src/PyCall.jl:85
 in fn at /Users/user/.julia/v0.3/PyCall/src/conversions.jl:181
 in writemime at /Users/user/.julia/v0.3/pyplot/src/pyplot.jl:140
 in base64 at base64.jl:125
 in display_dict at /Users/user/.julia/v0.3/IJulia/src/execute_request.jl:30
 in display at /Users/user/.julia/v0.3/IJulia/src/inline.jl:34
 in display at multimedia.jl:150

Clearly Plot3D cannot handle this difference well. However, it turns out that the required arguments xs, ys are robust to this whereas zs is not. Using the 3x1 Array{Int64,2} vectors again:

using PyPlot
close( gcf() )
plot3D( x, y )
display( gcf() )

Works fine.

Sorry for the very contrived example but this caused me some confusion earlier!
Thanks

@stevengj
Copy link
Member

Ideally, these bugs would be fixed upstream.... currently, Matplotlib is very inconsistent about accepting row vs. column vectors (some functions allow it, some don't), and PyPlot has to work around this.

I didn't implement any workarounds for keyword arguments yet, though. It should be straightforward.

@ghost
Copy link
Author

ghost commented May 30, 2014

These singleton arrays seem to be quite the nuisance, I do hope the julia dev team are going to do away with the ambiguity

@stevengj
Copy link
Member

@olaslett, I don't think that's going to happen. Unlike Matlab, Julia has 1d arrays (all arrays in Matlab are at least 2d). Unless Julia defines a separate Array type for row vectors, those will need to be 2d arrays.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant