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

get_legend_handles_labels() for errorbar plot not working properly #457

Open
carstenbauer opened this issue Sep 2, 2019 · 1 comment
Open

Comments

@carstenbauer
Copy link

carstenbauer commented Sep 2, 2019

Related to #401.

I'm simply trying to reverse the order of the legend entries of two errorbar plots.

Pure python (from within Julia):

py"""
import matplotlib.pyplot as plt
import numpy as np
plt.errorbar(np.random.rand(10), np.random.rand(10), np.random.rand(10), label='first', marker='o', linestyle="")
plt.errorbar(np.random.rand(10), np.random.rand(10), np.random.rand(10), label='second', marker='o', linestyle="")
h,l = plt.gca().get_legend_handles_labels()
plt.legend(reversed(h),reversed(l), frameon=True)
"""

image

Using PyPlot:

errorbar(rand(10), rand(10), rand(10), label="first", marker="o", linestyle="")
errorbar(rand(10), rand(10), rand(10), label="second", marker="o", linestyle="")
h,l = gca().get_legend_handles_labels()
legend(reverse(h),reverse(l), frameon=true)

image

Note that the handles are wrong (should be markers with error bars).

PyPlot + ugly fix:

errorbar(rand(10), rand(10), 0.1 .* rand(10), marker="o", linestyle="none", label="first")
errorbar(rand(10), rand(10), 0.1 .* rand(10), marker="o", linestyle="none", label="second")

py"""
import matplotlib.pyplot as plt
h, l = plt.gca().get_legend_handles_labels()
plt.legend(reversed(h), reversed(l), frameon=True)
"""

image

Presumably a PyObject conversion issue? In python, h is a container

[<ErrorbarContainer object of 3 artists>,
 <ErrorbarContainer object of 3 artists>]

In Julia I find

2-element Array{Tuple{PyObject,Tuple{PyObject,PyObject},Tuple{PyObject}},1}:
 (PyObject <matplotlib.lines.Line2D object at 0x000000006FAB9F98>, (PyObject <matplotlib.lines.Line2D object at 0x000000006FAD6780>, PyObject <matplotlib.lines.Line2D object at 0x000000006FAD6EF0>), (PyObject <matplotlib.collections.LineCollection object at 0x000000006FAD6320>,))
 (PyObject <matplotlib.lines.Line2D object at 0x000000006FADF860>, (PyObject <matplotlib.lines.Line2D object at 0x000000006FADFB70>, PyObject <matplotlib.lines.Line2D object at 0x000000006FADFCC0>), (PyObject <matplotlib.collections.LineCollection object at 0x000000006FADF550>,))
@stevengj
Copy link
Member

stevengj commented Sep 4, 2019

Yes, the issue is that since ErrorbarContainer is a subtype of tuple, PyCall is too aggressive about converting it to a Julia tuple. Yet another thing that will be eventually fixed by JuliaPy/PyCall.jl#617

For now, you can suppress the conversion with:

h,l = pycall(gca().get_legend_handles_labels, Tuple{Vector{PyObject}, Vector{String}})

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

2 participants