I've seen similar questions to this but not identical so I'll give it a shot here.
I have a plot and wish to have the user input curves (or any function) onto the plot. I currently have:
if args:
for arg in args:
ax.plot( t, arg, color = 'r' )
However, I get the error that iterables can't be callable. The problem is that the range of inputs (t) must be defined within the function itself so I can't do something like:
plotter( array, *[vonmises.pdf(t, 1), norm.pdf(t), some_other_curve(t)] )
because it doesn't know what 't' is until the function is called. Maybe my syntax is wrong. To be honest, I still don't fully understand *args and **kwargs, but I don't know if my lack of that understanding is the problem here. Preferably I would love to do something like this:
plotter( array, *[vonmises.pdf, norm.pdf] )
and then when it comes to plotting, explicitly state the input range. Halp? Full code for my function below:
import random
import math
import numpy as np
import matplotlib.pyplot as plt
color_list = [ 'b', 'g', 'r', 'c', 'y', 'm' ]
def histogram_and_curves( array, mean = 0.0, stdDev = 1.0, bins = None, xAxis = 'X', yAxis = 'Y', zAxis = 'Z', show = True, *curves ):
"""
Plots a histogram of a data array in 1 or 2 dimensions and an arbitrary number of PDFs for comparison.
"""
color = 'k'
bgcolor = 'w'
style = 'step'
fig = plt.figure( figsize = (6,6) )
if array.ndim is 1:
ax = fig.add_subplot( 111, facecolor = bgcolor )
if bins is None:
bins = np.arange( math.floor( np.amin( array ) ), math.ceil( np.amax( array ) ), 0.01 )
XMIN = mean - ( 4 * stdDev )
XMAX = mean + ( 4 * stdDev )
t = np.arange( XMIN , XMAX, 0.01)
xlim = ax.set_xlim( XMIN, XMAX )
ylim = ax.set_ylim( 0, 1 )
xText = ax.set_xlabel( xAxis )
yText = ax.set_ylabel( yAxis )
# Plot the 1D histogram
n, bins, patches = ax.hist( array, bins = bins, density = True, color = color, histtype = style )
# Plot distribution curves
if curves:
for curve in curves:
ax.plot( t, curve, color = random.choice( color_list ) )
if show:
plt.show()
else:
plt.close()
elif array.ndim is 2:
raise ValueError( "I'll come back for you..." )
else:
print( "Invalid dimensions. Required: 1 or 2. (Actual: {})".format( array.ndim ) )
return ax
You don't need to go into *args
and **kwargs
to achieve what you want. You can simply pass a list of functions:
import matplotlib.pyplot as plt
import numpy as np
def f1(x):
return x
def f2(x):
return x**2
def f3(x):
return x**(1/2)
def plotter(f_list):
x = np.linspace(0., 1.)
plt.figure()
for f in f_list:
plt.plot(x, f(x))
plotter([f1, f2, f3])
Output:
If you want to have an optional argument, you can do something like this:
def plotter(f_list=None):
...
if f_list:
for f in f_list:
...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.