PyCall.jl
PyCall.jl copied to clipboard
Slice indexing of python objects?
I'm trying to use GridSpec in matplotlib with PyCall, and ran into this error:
julia> using PyCall, PyPlot
# Make a GridSpec object
julia> gs_main = PyPlot.matplotlib[:gridspec][:GridSpec](1, 2)
PyObject <matplotlib.gridspec.GridSpec object at 0x7f3161b08828>
# In python, you can use slice indexing on a GridSpec object to make subplots
# However, the naive way of going about this doesn't work:
julia> gs_main[1:2]
ERROR: MethodError: no method matching getindex(::PyObject, ::UnitRange{Int64})
Closest candidates are:
getindex(::PyObject, ::Symbol) at /home/glynch/.julia/packages/PyCall/rUul9/src/PyCall.jl:294
getindex(::PyObject, ::AbstractString) at /home/glynch/.julia/packages/PyCall/rUul9/src/PyCall.jl:283
getindex(::PyObject, ::Integer) at /home/glynch/.julia/packages/PyCall/rUul9/src/PyCall.jl:755
...
Stacktrace:
[1] top-level scope at none:0
# Manually indexing with slice objects does work, however
julia> gs_main[:__getitem__](pybuiltin(:slice)(0, 2))
PyObject <matplotlib.gridspec.SubplotSpec object at 0x7f31636fe8d0>
Is there a more straight-forward way of accomplishing this?
One possibility would be for getindex
to call slice
automatically when it is passed a range. Will have to wait until #629 though, since we need to first change the getindex
api so that it no longers subtracts 1 from indices automatically.
I realise this is rather old now and PyCall is vastly different, but for GridSpec in particular the method I use is just to wrap it in a py call e.g taking one of the GridSpec examples:
using PyPlot
using PyCall
fig3 = plt.figure(constrained_layout=true)
gs = fig3.add_gridspec(3, 3)
f3_ax3 = fig3.add_subplot(py"$(gs)[1:, -1]")
f3_ax3.set_title("gs[1:, -1]")
f3_ax4 = fig3.add_subplot(py"$(gs)[-1, 0]")
f3_ax4.set_title("gs[-1, 0]")
f3_ax5 = fig3.add_subplot(py"$(gs)[-1, -2]")
f3_ax5.set_title("gs[-1, -2]")
f3_ax1 = fig3.add_subplot(py"$(gs)[0, :]")
f3_ax1.set_title("gs[0, :]")
f3_ax2 = fig3.add_subplot(py"$(gs)[1, :-1]")
f3_ax2.set_title("gs[1, :-1]")
f3_ax3 = fig3.add_subplot(py"$(gs)[1:, -1]")
f3_ax3.set_title("gs[1:, -1]")
f3_ax4 = fig3.add_subplot(py"$(gs)[-1, 0]")
f3_ax4.set_title("gs[-1, 0]")
f3_ax5 = fig3.add_subplot(py"$(gs)[-1, -2]")
f3_ax5.set_title("gs[-1, -2]")
Which seems to work fine.