2

I am drawing charts with matplotlib. When i am drawing it at the same chart with this code:

def draw0(x, ys, labels):


    plt.suptitle("big title")

    i =0
    for y in ys:
        plt.plot(x, y, label=labels[i])
        plt.scatter(x, y)  # dots
        plt.xticks(range(1, max(x) + 1))
        plt.grid(True)
        i+=1

    plt.figlegend(loc="upper left")

    plt.show()

    return

x = [1,2,3,4,5]
y1 = [1,3,5,7,9]
y2 = [10,30,50,70,90]
y3 = [0.1,0.3,0.5,0.7,0.9]

draw0(x, [y1, y2, y3], ["chart1", "chart2", "chart3"])

everything works fine. charts in one window But i need each chart to be at the separate subplot.

I am trying to do it like this:

def draw11(x, ys, labels):

    plt.figure()

    plt.suptitle("big title")

    i =0
    for y in ys:
        if i == 0:
            ax = plt.subplot(len(ys),1, i+1)
        else:
            plt.subplot(len(ys), 1, i + 1, sharex=ax)
        plt.plot(x, y, label=labels[i])
        plt.scatter(x, y)  # dots
        plt.xticks(range(1, max(x) + 1))
        plt.grid(True)
        i+=1

    plt.figlegend(loc="upper left")

    plt.show()

    return

I am getting this.

charts in sublots

Issue is that all charts have the same color. And legend is useless. How i can add automatic color management for all sublots? I'd like to have not the same colors there. Like subplot1.chart1 = color1, subplo1.chart2 = color2, sublot2.chart1 = color3, not color1.

2 Answers 2

17

Matplotlib has a built-in property cycler, which by default has 10 colors in it to cycle over. However those are cycled per axes. If you want to cycle over subplots you would need to use the cycler and get a new color from it for each subplot.

import matplotlib.pyplot as plt
colors = plt.rcParams["axes.prop_cycle"]()

def draw11(x, ys, labels):
    fig, axes = plt.subplots(nrows=len(ys), sharex=True)
    fig.suptitle("big title")

    for ax, y, label in zip(axes.flat, ys, labels):
        # Get the next color from the cycler
        c = next(colors)["color"]

        ax.plot(x, y, label=label, color=c)
        ax.scatter(x, y, color=c)  # dots
        ax.set_xticks(range(1, max(x) + 1))
        ax.grid(True)

    fig.legend(loc="upper left")
    plt.show()


x = [1,2,3,4,5]
y1 = [1,3,5,7,9]
y2 = [10,30,50,70,90]
y3 = [0.1,0.3,0.5,0.7,0.9]

draw11(x, [y1, y2, y3], ["chart1", "chart2", "chart3"])

enter image description here

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

7 Comments

Thank you very much. It looks like a solution i was looking for. I thought it is possible to somehow set the same color cycler to each subplot, but this solution will work too for me. Could you tell me, will next() loop colors from last one to first one at the end of 'colors'?
(1) The same color cycler is actually present in each axes, but it's not the same instance of the cycler; I think internally a copy of it is used. Hence each axes will start it at the first element. (2) Yes, it's not next that'll do it, but the cycler is really a cycler in the sense that next(c) will give you the first element once you've reached the end.
Basically the same answer I provided but instead of using costum colors this uses matplotlib default color list. You still have to specify the list "manually" by stating colors = plt.rcParams["axes.prop_cycle"](), so .@ilya your comments on my answer (given I indicated you could cycle over the list of colors) make no sense whatever.
plt.rcParams["axes.prop_cycle"] gets you the colors from the style sheet. If you use a different style sheet you get different colors. Also a cycler will cycle, so no need to care about it reaching the end. In that sense it's rather automatic, i.e. no need to type in '#1f77b4' or so. The reason it doesn't get more automatic than that is that from the design perspective you'd rather want to have each axes have its own cycler.
"I think internally a copy of it is used" — if I have it correct, every axes uses the same cycler but a different instance of the itertools.cycle that cycler_object() returns.
|
1

Just have a list of colors and select them for each plt.plot and plt.scatter.

colors = ['orange', 'cyan', 'green']
i =0
for y in ys:
        if i == 0:
            ax = plt.subplot(len(ys),1, i+1)
        else:
            plt.subplot(len(ys), 1, i + 1, sharex=ax)
        plt.plot(x, y, label=labels[i], c=colors[i])
        plt.scatter(x, y, c=colors[i])  # dots
        plt.xticks(range(1, max(x) + 1))
        plt.grid(True)
        i+=1

9 Comments

Replace c=color[i] by c=colors[i]
yeap was a typo, just fixed it.
It wont work for me, since there can be more than 3 subplots. Thats why i asked about automatic color management.
And you should have included this information in the question, otherwise is misleading and a waste of time for everybody.
Please read last part of my question. Word 'automatic' made bold especially for such answers.
|

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.