2

Every week I am plotting figures using pyplot and after doing this for a year and improving on how my figures look, I decided I want to throw as much code from what I have in EVERY script EVERY week into an external file.

In the file, there are:

# 1. custom functions (they get something and return something)     
    def cf(self, string):
        if (string=="-"):
            ret = 0
        else:
            ret = float(string.replace(",", "."))
        return ret

# 2. import of numpy and matplotlib.pyplot as np and plt

    import numpy as np
    from numpy import log as ln
    from numpy import log10 as log
    import matplotlib.pyplot as plt

# 3. import of "rc" from "matplotlib" and pass settings to it (i.e. font, use of LaTeX, ...)

    from matplotlib import rc
        if (setting=="tex"):
            rc('font',**{'family':'serif', 'serif':['Computer Modern'], 'size':18})
            rc('text', usetex=True)
            rc('text.latex', unicode=True)
            rc('axes.formatter', use_locale=True)
        if (setting=="fast"):
            rc('font',**{'family':'sans-serif', 'sans-serif':['Verdana'], 'size':15})

# 4. custom functions that make something easier (for example I have a new function for numpy.loadtxt() in order to work around decimal commas instead of decimal points)

    def loadtxt(self, numcols=2, name="", decimal=",", skiprows=0):
        if (name==""):
            name = self.script_name()+".txt"
        if (decimal==","):
            converters = {i:self.cf for i in range (0,numcols) }
        return np.loadtxt(name, converters=converters, skiprows=skiprows)

The thing I am asking is: How to do this properly and most comfortably? So far I imported the whole code as a module and instead of using plt.foo(), I used mymodule.foo() and wrote a handler in mymodule like so:

def semilogy(self, *args, **kwargs):
    plt.semilogy(*args, **kwargs)

def plot(self, *args, **kwargs):
    plt.plot(*args, **kwargs)

def loglog(self, *args, **kwargs):
    plt.loglog(*args, **kwargs)

which TBH feels... suboptimal if not stupid. It also is very impractical whenever I want a new unmodified function from plt and I have to write a new handler into my module. If it was PHP, I'd probably go with a simple "include_once()" with all the code and I could refer to everything as if I included it directly in the script.


BONUS QUESTION: How to properly write a handler for the np.loadtxt() that would pass ALL arguments received except one that should be set by the handler?

def myloadtxt (self, *args, **kwargs, decimal):
    if (decimal==","):
        converters = {i:myconverterfunction() for i in range (0,number_of_columns) }
    return np.loadtxt(*args, **kwargs, converters=converters)

EDIT: I will gladly elaborate on anything. I am aware that I don't have an absolutely precise idea of what I want, but anyone who ever plotted more than one figure with matplotlib should be able to feel what I need.

6
  • what's wrong with having them in myshortcuts.py along the module path, or current directory, and doing from myshortcuts import *? Commented Mar 18, 2015 at 18:39
  • import * is not the best practice when it comes to import modules. You want to avoid namespace issues @AnttiHaapala. Have you tried tried turning all your code into one module so that all you need is one import. Commented Mar 18, 2015 at 18:44
  • there are no namespace issues if it is his own shortcut module @hrand Commented Mar 18, 2015 at 18:44
  • @AnttiHaapala this would work for my own functions, but will this also do the imports and all the rc settings? Commented Mar 18, 2015 at 18:59
  • if you'd import them into this file, then yes from myshortcuts import * would import those names too. Commented Mar 18, 2015 at 19:01

1 Answer 1

1

You might want to look at what Seaborn does:

http://stanford.edu/~mwaskom/software/seaborn/index.html

You just import it and select a style, which modifies your Matplotlib behind the scenes:

http://stanford.edu/~mwaskom/software/seaborn/tutorial/aesthetics.html

There are also further tweaks it provides.

Given that, you can either use it and write your own style, or do whatever it does to Matplotlib. Once it is set up, it seems quite clean from the user's perspective.


As for the bonus, I don't think your myloadtxt will work - you have a non-keyword argument after *args and **kwargs. I think you want to inspect if decimal is in the keys of kwargs and if it is, remove it from the dictionary, do what you need to do and add it back to the dictionary. Then just pass *args and **kwargs to loadtxt.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.