1

I'm trying to write a small package that adds a function to the plotly.express package. I'm trying to get this to work:

>>> import plotly.express as px
>>> import plotly_ecdf
>>> px.ecdf()
'ECDF plot here!'

This actually works as is with this in plotly_ecdf.py:

# plotly_ecdf.py

import plotly.express as px


def ecdf():
    print("ECDF plot here!")


px.ecdf = ecdf

What's weird is that if I haven't already imported plotly.express, the plotly_ecdf import also fails:

>>> import plotly_ecdf
>>> px.ecdf()
NameError: name 'px' is not defined

I tried making use of this response. I can access and write variables when called in a function, but I can't it to work during an import statement.

So how do I modify plotly_ecdf.py to check if plotly.express is already imported so I can throw an error if it isn't? Bonus points if this can modify whatever alias plotly.express has been assigned to. Thanks in advance!

Ben Lindsay
  • 1,686
  • 4
  • 23
  • 44
  • Not sure why you are trying to monkey-patch plotly.express. Regardless, `px` is only defined (in-scope) in your `plotly_ecdf.py` file. `ecdf()` is defined in the scope `plotly.express` - add `import plotly.express` before and try `plotly.express.ecdf()` – DisappointedByUnaccountableMod Sep 07 '20 at 21:27
  • This is a good example of trying to make a language do what you'd like it to, instead of using it how it was designed. Don't. It doesn't help your future self and it certainly won't be appreciated by anyone else that has to read your code. If you share *why* you're trying to do this and what you're hoping to achieve, someone may be able to tell you how to go about it. – Grismar Sep 07 '20 at 21:35

1 Answers1

1

I don't think I fully understand what you want. If this is meant to be a library that adds to the existing plotly.express package then I would recommend turning plotly_ecdf.py into a proper python package with a setup.py and then making plotly a requirement.

Trying to do it another way doesn't seem like a good idea. Though if you want you could do:

try:
    import plotly.express as px

except NameError:
    print("Plotly.express not installed \nPlease install using pip install plotly")

but I would recommend against it since band-aid solutions always fail down the line.

EDIT Based on your comment you could also just do it simply by having your directory tree setup like this:

plotly_ecdf.py
requirements.txt
readme.md

Then specify inside requirements.txt:

plotly

And add a line to your README with

## Dependencies

install all dependencies by running ```pip install -r requirements.txt```
Kieran Wood
  • 1,297
  • 8
  • 15
  • I'm trying to do something sort of similar to pyjanitor (https://pyjanitor.readthedocs.io/) which modifies pandas to add convenience methods. I'm just trying to monkeypatch plotly express in lieu of creating a full-on pull request to plotly. I'll probably just end up creating package with a standalone function based on the responses I'm getting though – Ben Lindsay Sep 08 '20 at 00:06
  • @BenLindsay I added another explanation to the end that is the shortest way. This still won't let you install the function, but if it's just a wrapper within a project it's an option. If you want to see an example of a package of "helper" functions I made one here: https://github.com/Descent098/sdu – Kieran Wood Sep 08 '20 at 00:57
  • Thanks for the input, and sorry if my question wasn't clear, but I get how to make plotly a dependency/requirement using setup.py. My goal was to try to enable my first block of code to work, so that running `import plotly_ecdf` modified the already imported plotly.express module to add an ecdf function to it. That's more complicated than just adding plotly to the `requirements` variable of setup.py, because I would need to access the `px` variable from the original scope. Based on feedback from you and others though, I'm leaning away from this setup – Ben Lindsay Sep 08 '20 at 04:14