5

I would like to plot one ore more signals into one plot.

For each signal, a individual color, linewidth and linestyle may be specified. If multiple signals have to be plotted, a legend should be provided as well.

So far, I use the following code which allows me to plot up to three signals.

import matplotlib
fig = matplotlib.figure.Figure(figsize=(8,6))
subplot = fig.add_axes([0.1, 0.2, 0.8, 0.75])
Signal2, Signal3, legend, t = None, None, None, None
Signal1, = subplot.plot(xDataSignal1, yDataSignal1, color=LineColor[0], linewidth=LineWidth[0],linestyle=LineStyle[0])
if (yDataSignal2 != [] and yDataSignal3 != []):
    Signal2, = subplot.plot(xDataSignal2, yDataSignal2, color=LineColor[1], linewidth=LineWidth[1],linestyle=LineStyle[1])
    Signal3, = subplot.plot(xDataSignal3, yDataSignal3, color=LineColor[2], linewidth=LineWidth[2],linestyle=LineStyle[2])
    legend = subplot.legend([Signal1, Signal2, Signal3], [yLabel[0], yLabel[1], yLabel[2]],LegendPosition,labelspacing=0.1, borderpad=0.1)
    legend.get_frame().set_linewidth(0.5)
    for t in legend.get_texts():
        t.set_fontsize(10)
elif (yDataSignal2 != []):
    Signal2, = subplot.plot(xDataSignal2, yDataSignal2, color=LineColor[1], linewidth=LineWidth[1],linestyle=LineStyle[1])
    legend = subplot.legend([Signal1, Signal2], [yLabel[0], yLabel[1]], LegendPosition,labelspacing=0.1, borderpad=0.1)
    legend.get_frame().set_linewidth(0.5)
    for t in legend.get_texts():
        t.set_fontsize(10)

Is it possible to generalize that code such that it is more Pythonic and supports up to n signals by still making use of matplotlib and subplot?

Any suggestions are highly appreciated.

Rickson
  • 1,040
  • 2
  • 16
  • 40
  • 2
    How about you create some kind of list of dict, where each element of the list is a dict which will have your x and y data, the linecolor, the linewidth, etc. Then you can just create a plot, iterate on said list of dict and plot everything the same axis? – Julien Marrec Dec 12 '16 at 14:49
  • Good remark. I will give this a try. Thx. – Rickson Dec 12 '16 at 14:54

1 Answers1

14

A list of dicts might be a good solution for this (you could even use a defaultdict to default the color and linewidth in case you don't want to specify it, read more here)

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

mysignals = [{'name': 'Signal1', 'x': np.arange(10,20,1),
             'y': np.random.rand(10), 'color':'r', 'linewidth':1},
            {'name': 'Signal2', 'x': np.arange(10,20,1),
             'y': np.random.rand(10), 'color':'b', 'linewidth':3},
            {'name': 'Signal3', 'x': np.arange(10,20,1),
             'y': np.random.rand(10), 'color':'k', 'linewidth':2}]

fig, ax = plt.subplots()
for signal in mysignals:
    ax.plot(signal['x'], signal['y'], 
            color=signal['color'], 
            linewidth=signal['linewidth'],
            label=signal['name'])

# Enable legend
ax.legend()
ax.set_title("My graph")
plt.show()

enter image description here

Community
  • 1
  • 1
Julien Marrec
  • 11,605
  • 4
  • 46
  • 63