1

I want to create a module for a custom plot drawing for my scientific data, but I do not know how to pass an argument of type (*arg2,**kwarg2) to a method.

Here is the relevant code:

import numpy as np
import matplotlib.pyplot as plt

# class of figures for channel flow
# with one subfigure

class Homfig:

    # *args: list of plot features for ax1.plot
    #     (xdata,ydata,str linetype,str label)
    # **kwargs: list of axes features for ax1.set_$(STH)
    #     possible keys:
    #     title,xlabel,ylabel,xlim,ylim,xscale,yscale

    def __init__(self,*args,**kwargs):
        self.args = args
        self.kwargs = kwargs
        self.fig = plt.figure()
        self.ax = self.fig.add_subplot(111)

        for key, val in self.kwargs.iteritems():
            getattr(self.ax,'set_'+key)(val)

    def hdraw(self):
        for arg in self.args:
            self.ax.plot(*arg)
            leg = self.ax.legend(loc=4)

The problem is that arg is itself a tuple like (*agr2,**kwarg2) and when I call self.ax.plot(*arg) it does not see named variables. Function hdraw should operate on the input it got in *args from init, and data for plot lines are passed in arg. How can I express that arg consists of unnamed and named variables? self.ax.plot may be called more then once, when I want to have several lines (with different label, linetype, etc., in one plot.)

I call the module from other python script with:

meanfig = hfig.Homfig((datax,datay),title='test plot')
meanfig.hdraw()

How can I add features like label or linetype to the self.ax.plot, for example:

meanfig = hfig.Homfig((datax,datay,label="test_label",linetype ='o'),title='test plot')
Maria
  • 84
  • 4
  • 9
  • Possible duplicate of [Pass all arguments of a function to another function](https://stackoverflow.com/questions/42499656/pass-all-arguments-of-a-function-to-another-function) – Nick Chapman Jul 05 '17 at 13:52

1 Answers1

1

You should be able to pass them using double **, i.e.

def hdraw(self):
    self.ax.plot(*self.args, **self.kwargs)
    leg = self.ax.legend(loc=4)

and then call it using

meanfig = hfig.Homfig(datax, datay, label="test_label", linetype ='o', title='test plot')

Update according to comment:

If you want to draw multiple plots in the same figure, that will be hard in the way you wrote, but you could do it like this

class Homfig:
    def __init__(self, title):
        self.fig = plt.figure()
        self.ax = self.fig.add_subplot(111)

        self.args = []
        self.kwargs = []

    def add_plot(self, *args, **kwargs):
        self.args.append(args)
        self.kwargs.append(kwargs)

    def hdraw(self):
        for args, kwargs in zip(self.args, self.kwargs):
            self.ax.plot(*args, **kwargs)
        leg = self.ax.legend(loc=4)

and then call it using

meanfig = hfig.Homfig(title='test plot')
meanfig.add_plot(datax, datay, label="test_label", linetype ='o')
meanfig.add_plot(datax, 2 * datay, label="test_label_2", linetype ='o')
meanfig.hdraw()
Jonas Adler
  • 10,365
  • 5
  • 46
  • 73
  • here,` kwargs` are used for axes variables. I want to put several plots in one figure, so there will be more than one call for `self.ax.plot` – Maria Jul 05 '17 at 14:16
  • 1
    See the updated answer for a way to do this then. Sadly, doing it only in the `__init__` method would be hard to do in a nice way. – Jonas Adler Jul 05 '17 at 14:47
  • The `title` in `__init__` is redundant. But otherwise this works nicely, thanks :) – Tom May 12 '23 at 14:54