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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange legend layout #482

Closed
Juanlu001 opened this Issue Nov 2, 2018 · 7 comments

Comments

3 participants
@Juanlu001
Copy link
Member

Juanlu001 commented Nov 2, 2018

馃悶 Problem

In certain peculiar cases, the legend of OrbitPlotter gets out of the axes rectangle, either with matplotlib 2.2.3 or 3.0:

https://gist.github.com/Juanlu001/7ea242431b43fafffd73416fa93024c9

screenshot_2018-11-02 talk-copy1 1

馃枼 Please paste the output of following commands

  • conda info -a (only if you have conda)
  • conda list (only if you have conda)
  • pip freeze
     active environment : poliastro37
    active env location : /home/juanlu/.miniconda36/envs/poliastro37
            shell level : 1
       user config file : /home/juanlu/.condarc
 populated config files : /home/juanlu/.miniconda36/.condarc
                          /home/juanlu/.condarc
          conda version : 4.5.11
    conda-build version : 3.12.1
         python version : 3.6.5.final.0
       base environment : /home/juanlu/.miniconda36  (writable)
           channel URLs : https://repo.anaconda.com/pkgs/main/linux-64
                          https://repo.anaconda.com/pkgs/main/noarch
                          https://repo.anaconda.com/pkgs/free/linux-64
                          https://repo.anaconda.com/pkgs/free/noarch
                          https://repo.anaconda.com/pkgs/r/linux-64
                          https://repo.anaconda.com/pkgs/r/noarch
                          https://repo.anaconda.com/pkgs/pro/linux-64
                          https://repo.anaconda.com/pkgs/pro/noarch
                          https://conda.anaconda.org/conda-forge/linux-64
                          https://conda.anaconda.org/conda-forge/noarch
          package cache : /home/juanlu/.miniconda36/pkgs
                          /home/juanlu/.conda/pkgs
       envs directories : /home/juanlu/.miniconda36/envs
                          /home/juanlu/.conda/envs
               platform : linux-64
             user-agent : conda/4.5.11 requests/2.18.4 CPython/3.6.5 Linux/4.15.0-38-generic linuxmint/19 glibc/2.27
                UID:GID : 1000:1000
             netrc file : /home/juanlu/.netrc
           offline mode : False

# conda environments:
#
base                     /home/juanlu/.miniconda36
_test36                  /home/juanlu/.miniconda36/envs/_test36
_test36_2                /home/juanlu/.miniconda36/envs/_test36_2
api36                    /home/juanlu/.miniconda36/envs/api36
astropy36_dev            /home/juanlu/.miniconda36/envs/astropy36_dev
brte36                   /home/juanlu/.miniconda36/envs/brte36
brte36dsk18              /home/juanlu/.miniconda36/envs/brte36dsk18
bts36                    /home/juanlu/.miniconda36/envs/bts36
geostore36               /home/juanlu/.miniconda36/envs/geostore36
gmat36                   /home/juanlu/.miniconda36/envs/gmat36
marvin34                 /home/juanlu/.miniconda36/envs/marvin34
marvin36                 /home/juanlu/.miniconda36/envs/marvin36
mbd36                    /home/juanlu/.miniconda36/envs/mbd36
pgadmin4                 /home/juanlu/.miniconda36/envs/pgadmin4
poliastro36              /home/juanlu/.miniconda36/envs/poliastro36
poliastro36_             /home/juanlu/.miniconda36/envs/poliastro36_
poliastro36_stable       /home/juanlu/.miniconda36/envs/poliastro36_stable
poliastro37           *  /home/juanlu/.miniconda36/envs/poliastro37
poliastro37_new          /home/juanlu/.miniconda36/envs/poliastro37_new
propan36                 /home/juanlu/.miniconda36/envs/propan36
py34                     /home/juanlu/.miniconda36/envs/py34
py36                     /home/juanlu/.miniconda36/envs/py36
                         /home/juanlu/.miniconda36/envs/py36/conda-bld/cspice_1529866334362/_build_env
                         /home/juanlu/.miniconda36/envs/py36/conda-bld/cspice_1529866449168/_build_env
                         /home/juanlu/.miniconda36/envs/py36/conda-bld/cspice_1529866543542/_build_env
py37                     /home/juanlu/.miniconda36/envs/py37
py37_def                 /home/juanlu/.miniconda36/envs/py37_def
pypiserver36             /home/juanlu/.miniconda36/envs/pypiserver36
pyrenfe36                /home/juanlu/.miniconda36/envs/pyrenfe36
scipy37_dev              /home/juanlu/.miniconda36/envs/scipy37_dev
spice37                  /home/juanlu/.miniconda36/envs/spice37
telluric36               /home/juanlu/.miniconda36/envs/telluric36
tp36                     /home/juanlu/.miniconda36/envs/tp36
unitshack36              /home/juanlu/.miniconda36/envs/unitshack36
                         /home/juanlu/Development/poliastro/benchmarks/env/1e6a43cbb25dbca4e803dce4b31b80e5
                         /home/juanlu/Development/poliastro/benchmarks/env/4ef9678914ff6e01972901ec0de8ad50

sys.version: 3.6.5 | packaged by conda-forge | (defau...
sys.prefix: /home/juanlu/.miniconda36
sys.executable: /home/juanlu/.miniconda36/bin/python
conda location: /home/juanlu/.miniconda36/lib/python3.6/site-packages/conda
conda-build: /home/juanlu/.miniconda36/bin/conda-build
conda-convert: /home/juanlu/.miniconda36/bin/conda-convert
conda-develop: /home/juanlu/.miniconda36/bin/conda-develop
conda-env: /home/juanlu/.miniconda36/bin/conda-env
conda-index: /home/juanlu/.miniconda36/bin/conda-index
conda-inspect: /home/juanlu/.miniconda36/bin/conda-inspect
conda-metapackage: /home/juanlu/.miniconda36/bin/conda-metapackage
conda-render: /home/juanlu/.miniconda36/bin/conda-render
conda-skeleton: /home/juanlu/.miniconda36/bin/conda-skeleton
conda-smithy: /home/juanlu/.miniconda36/bin/conda-smithy
conda-verify: /home/juanlu/.miniconda36/bin/conda-verify
user site dirs: 

CIO_TEST: <not set>
CONDA_DEFAULT_ENV: poliastro37
CONDA_EXE: /home/juanlu/.miniconda36/bin/conda
CONDA_PREFIX: /home/juanlu/.miniconda36/envs/poliastro37
CONDA_PROMPT_MODIFIER: (poliastro37) 
CONDA_PYTHON_EXE: /home/juanlu/.miniconda36/bin/python
CONDA_ROOT: /home/juanlu/.miniconda36
CONDA_SHLVL: 1
DEFAULTS_PATH: /usr/share/gconf/cinnamon.default.path
MANDATORY_PATH: /usr/share/gconf/cinnamon.mandatory.path
PATH: /home/juanlu/.miniconda36/envs/poliastro37/bin:/home/juanlu/.rbenv/bin:$/home/juanlu/.rbenv/shims:/home/juanlu/.gem/ruby/2.3.0/bin:/home/juanlu/.local/share/umake/bin:/home/juanlu/bin:/home/juanlu/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
REQUESTS_CA_BUNDLE: <not set>
SSL_CERT_FILE: <not set>
XDG_SEAT_PATH: /org/freedesktop/DisplayManager/Seat0
XDG_SESSION_PATH: /org/freedesktop/DisplayManager/Session0


WARNING: could not import _license.show_info
# try:
# $ conda install -n root _license
# packages in environment at /home/juanlu/.miniconda36/envs/poliastro37:
#
# Name                    Version                   Build  Channel
alabaster                 0.7.11                    <pip>
asn1crypto                0.24.0                    <pip>
astropy                   3.0.4                     <pip>
astroquery                0.3.8                     <pip>
atomicwrites              1.1.5                     <pip>
attrs                     18.1.0                    <pip>
Babel                     2.6.0                     <pip>
backcall                  0.1.0                     <pip>
beautifulsoup4            4.6.3                     <pip>
bleach                    2.1.4                     <pip>
bzip2                     1.0.6                h470a237_2    conda-forge
ca-certificates           2018.8.24            ha4d7672_0    conda-forge
certifi                   2018.4.16                py37_0    conda-forge
cffi                      1.11.5                    <pip>
chardet                   3.0.4                     <pip>
coverage                  4.5.1                     <pip>
cryptography              2.3.1                     <pip>
cspice                    66                   h470a237_3    conda-forge
cycler                    0.10.0                    <pip>
decorator                 4.3.0                     <pip>
defusedxml                0.5.0                     <pip>
docutils                  0.14                      <pip>
entrypoints               0.2.3                     <pip>
flake8                    3.6.0                     <pip>
gmp                       6.1.2                hfc679d8_0    conda-forge
html5lib                  1.0.1                     <pip>
hypothesis                3.73.0                    <pip>
idna                      2.7                       <pip>
imagesize                 1.0.0                     <pip>
ipykernel                 4.8.2                     <pip>
ipython                   6.5.0                     <pip>
ipython-genutils          0.2.0                     <pip>
ipywidgets                7.4.0                     <pip>
jedi                      0.12.1                    <pip>
jeepney                   0.3.1                     <pip>
Jinja2                    2.10                      <pip>
jplephem                  2.8                       <pip>
jsonschema                2.6.0                     <pip>
jupyter                   1.0.0                     <pip>
jupyter-client            5.2.3                     <pip>
jupyter-console           5.2.0                     <pip>
jupyter-core              4.4.0                     <pip>
keyring                   13.2.1                    <pip>
kiwisolver                1.0.1                     <pip>
libffi                    3.2.1                hfc679d8_4    conda-forge
libgcc                    7.2.0                h69d50b8_2    conda-forge
libgcc-ng                 7.2.0                hdf63c60_3    conda-forge
libstdcxx-ng              7.2.0                hdf63c60_3    conda-forge
llvmlite                  0.24.0                    <pip>
MarkupSafe                1.0                       <pip>
matplotlib                2.2.3                     <pip>
mccabe                    0.6.1                     <pip>
mistune                   0.8.3                     <pip>
more-itertools            4.3.0                     <pip>
mypy                      0.620                     <pip>
nbconvert                 5.4.0                     <pip>
nbformat                  4.4.0                     <pip>
nbsphinx                  0.3.4                     <pip>
ncurses                   6.1                  hfc679d8_1    conda-forge
notebook                  5.7.0                     <pip>
numba                     0.39.0                    <pip>
numpy                     1.15.1                    <pip>
openssl                   1.0.2p               h470a237_0    conda-forge
packaging                 17.1                      <pip>
pandas                    0.23.4                    <pip>
pandoc                    2.2.2                         1    conda-forge
pandocfilters             1.4.2                     <pip>
parso                     0.3.1                     <pip>
pexpect                   4.6.0                     <pip>
pickleshare               0.7.4                     <pip>
pip                       18.0                     py37_1    conda-forge
pkginfo                   1.4.2                     <pip>
plotly                    3.1.1                     <pip>
pluggy                    0.7.1                     <pip>
poliastro                 0.12.dev0                 <pip>
prometheus-client         0.3.1                     <pip>
prompt-toolkit            1.0.15                    <pip>
ptyprocess                0.6.0                     <pip>
py                        1.5.4                     <pip>
pycodestyle               2.4.0                     <pip>
pycparser                 2.18                      <pip>
pyflakes                  2.0.0                     <pip>
Pygments                  2.2.0                     <pip>
pyparsing                 2.2.0                     <pip>
pytest                    3.8.0                     <pip>
pytest-cov                2.5.1                     <pip>
python                    3.7.0                h5001a0f_0    conda-forge
python-dateutil           2.7.3                     <pip>
pytz                      2018.5                    <pip>
pyzmq                     17.1.2                    <pip>
qtconsole                 4.4.1                     <pip>
readline                  7.0                  haf1bffa_1    conda-forge
requests                  2.19.1                    <pip>
requests-toolbelt         0.8.0                     <pip>
retrying                  1.3.3                     <pip>
rise                      5.4.1                     <pip>
scipy                     1.1.0                     <pip>
SecretStorage             3.0.1                     <pip>
Send2Trash                1.5.0                     <pip>
setuptools                40.2.0                   py37_0    conda-forge
simplegeneric             0.8.1                     <pip>
six                       1.11.0                    <pip>
snowballstemmer           1.2.1                     <pip>
Sphinx                    1.7.7                     <pip>
sphinx-rtd-theme          0.4.1                     <pip>
sphinxcontrib-websupport  1.1.0                     <pip>
sqlite                    3.24.0               h2f33b56_0    conda-forge
terminado                 0.8.1                     <pip>
testpath                  0.3.1                     <pip>
tk                        8.6.8                         0    conda-forge
tornado                   5.1                       <pip>
tqdm                      4.25.0                    <pip>
traitlets                 4.3.2                     <pip>
twine                     1.11.0                    <pip>
typed-ast                 1.1.0                     <pip>
urllib3                   1.23                      <pip>
versioneer                0.18                      <pip>
wcwidth                   0.1.7                     <pip>
webencodings              0.5.1                     <pip>
wheel                     0.31.1                   py37_1    conda-forge
widgetsnbextension        3.4.0                     <pip>
xz                        5.2.4                h470a237_1    conda-forge
zlib                      1.2.11               h470a237_3    conda-forge
alabaster==0.7.11
asn1crypto==0.24.0
astropy==3.0.4
astroquery==0.3.8
atomicwrites==1.1.5
attrs==18.1.0
Babel==2.6.0
backcall==0.1.0
beautifulsoup4==4.6.3
bleach==2.1.4
certifi==2018.4.16
cffi==1.11.5
chardet==3.0.4
coverage==4.5.1
cryptography==2.3.1
cycler==0.10.0
decorator==4.3.0
defusedxml==0.5.0
docutils==0.14
entrypoints==0.2.3
flake8==3.6.0
html5lib==1.0.1
hypothesis==3.73.0
idna==2.7
imagesize==1.0.0
ipykernel==4.8.2
ipython==6.5.0
ipython-genutils==0.2.0
ipywidgets==7.4.0
jedi==0.12.1
jeepney==0.3.1
Jinja2==2.10
jplephem==2.8
jsonschema==2.6.0
jupyter==1.0.0
jupyter-client==5.2.3
jupyter-console==5.2.0
jupyter-core==4.4.0
keyring==13.2.1
kiwisolver==1.0.1
llvmlite==0.24.0
MarkupSafe==1.0
matplotlib==2.2.3
mccabe==0.6.1
mistune==0.8.3
more-itertools==4.3.0
mypy==0.620
nbconvert==5.4.0
nbformat==4.4.0
nbsphinx==0.3.4
notebook==5.7.0
numba==0.39.0
numpy==1.15.1
packaging==17.1
pandas==0.23.4
pandocfilters==1.4.2
parso==0.3.1
pexpect==4.6.0
pickleshare==0.7.4
pkginfo==1.4.2
plotly==3.1.1
pluggy==0.7.1
-e git+git@github.com:Juanlu001/poliastro.git@7d6c9702dc2a6295c3c79b3ded5600c37bdeed3f#egg=poliastro
prometheus-client==0.3.1
prompt-toolkit==1.0.15
ptyprocess==0.6.0
py==1.5.4
pycodestyle==2.4.0
pycparser==2.18
pyflakes==2.0.0
Pygments==2.2.0
pyparsing==2.2.0
pytest==3.8.0
pytest-cov==2.5.1
python-dateutil==2.7.3
pytz==2018.5
pyzmq==17.1.2
qtconsole==4.4.1
requests==2.19.1
requests-toolbelt==0.8.0
retrying==1.3.3
rise==5.4.1
scipy==1.1.0
SecretStorage==3.0.1
Send2Trash==1.5.0
simplegeneric==0.8.1
six==1.11.0
snowballstemmer==1.2.1
Sphinx==1.7.7
sphinx-rtd-theme==0.4.1
sphinxcontrib-websupport==1.1.0
terminado==0.8.1
testpath==0.3.1
tornado==5.1
tqdm==4.25.0
traitlets==4.3.2
twine==1.11.0
typed-ast==1.1.0
urllib3==1.23
versioneer==0.18
wcwidth==0.1.7
webencodings==0.5.1
widgetsnbextension==3.4.0

馃幆 Goal

Fix this unsurprisingly ugly result.

馃挕 Possible solutions

This comes from the black magic we are doing with the figure legend in matplotlib, that's for sure:

if label:
# This will apply the label to either the point or the osculating
# orbit depending on the last plotted line, as they share variable
if not self.ax.get_legend():
size = self.ax.figure.get_size_inches() + [8, 0]
self.ax.figure.set_size_inches(size)
label = _generate_label(orbit, label)
l.set_label(label)
self.ax.legend(bbox_to_anchor=(1.05, 1), title="Names and epochs")

Ideas:

  • Debug what exactly is going on (brave souls welcome)
  • Find an alternative way to achieve a similar result
  • Give up and wait for #481

馃搵 Steps to solve the problem

  • Comment below about what you've started working on.
  • Add, commit, push your changes
  • Submit a pull request and add this in comments - Addresses #<put issue number here>
  • Ask for a review in comments section of pull request
  • Celebrate your contribution to this project 馃帀
@ImportanceOfBeingErnest

This comment has been minimized.

Copy link

ImportanceOfBeingErnest commented Nov 2, 2018

The reason for the issue is that no loc is specified in the legend call. It will hence choose "best", which isn't always best, especially when the legend is outside the axes.

Solution: specify the location e.g.

self.ax.legend(bbox_to_anchor=(1.05, 1), loc="upper left", title="Names and epochs")
@Juanlu001

This comment has been minimized.

Copy link
Member

Juanlu001 commented Nov 3, 2018

Hi @ImportanceOfBeingErnest, thanks a lot for the suggestion! The problem with this is that the legend was falling inside the axes, which is another thing I wanted to avoid. The best thing I could do is to set loc=(1.05, 0.5), because the origin of coordinates is in the bottom-left corner and therefore I cannot adjust it to the upper-right corner without knowing the height of the legend in advance:

screenshot_2018-11-03 legend-issue

In any case, this is decently good for me. Do you have a better suggestion?

@Juanlu001

This comment has been minimized.

Copy link
Member

Juanlu001 commented Nov 3, 2018

Oh, it seems I was using the wrong loc parameter because I misunderstood its intent! PR incoming. Thanks again!

Juanlu001 added a commit to Juanlu001/poliastro that referenced this issue Nov 3, 2018

@wafflebot wafflebot bot added the 2 - In Progress label Nov 3, 2018

Juanlu001 added a commit to Juanlu001/poliastro that referenced this issue Nov 3, 2018

Juanlu001 added a commit to Juanlu001/poliastro that referenced this issue Nov 3, 2018

Juanlu001 added a commit to Juanlu001/poliastro that referenced this issue Nov 9, 2018

@AntoniiaK

This comment has been minimized.

Copy link
Contributor

AntoniiaK commented Nov 28, 2018

Hello. I repeated your example and I see that legends looks like in first post in second picture. May be little tuning will be better?
legend

@Juanlu001

This comment has been minimized.

Copy link
Member

Juanlu001 commented Nov 28, 2018

Hi! Instead of Time.now(), can you try to reproduce with Time("2018-11-02 04:57:00", scale="tdb"), which is the original date when I found this?

@AntoniiaK

This comment has been minimized.

Copy link
Contributor

AntoniiaK commented Nov 28, 2018

Yes I can.
legend2018

@Juanlu001

This comment has been minimized.

Copy link
Member

Juanlu001 commented Nov 29, 2018

Interesting... Well, that makes everything more problematic because it's not even deterministic, or there is some other factor that we are not taking into account. Perhaps a new matplotlib release.

In any case, the root cause seems to be that, by default, the legend is placed in a more or less automatic fashion (loc="best"), and I found that changing that fixed the issue for me:

diff --git a/src/poliastro/plotting/static.py b/src/poliastro/plotting/static.py
--- a/src/poliastro/plotting/static.py
+++ b/src/poliastro/plotting/static.py
@@ -195,8 +198,7 @@ def plot(self, orbit, label=None, color=None, method=mean_motion):
                 self.ax.figure.set_size_inches(size)
             label = _generate_label(orbit, label)
             l.set_label(label)
-            self.ax.legend(bbox_to_anchor=(1.05, 1), title="Names and epochs")
+            self.ax.legend(loc="upper left", bbox_to_anchor=(1.05, 1), title="Names and epochs")
 
         self.ax.set_xlabel("$x$ (km)")
         self.ax.set_ylabel("$y$ (km)")

@AntoniiaK I know it's a small change but nobody did a PR for it yet, so if you want to do it, all yours!

@Juanlu001 Juanlu001 closed this in 9cc569e Dec 1, 2018

@wafflebot wafflebot bot removed the 2 - In Progress label Dec 1, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment