পাইথন একাধিক বার ম্যাটপ্লটলিব


92

ম্যাটপ্লটলিবে একাধিক বার কীভাবে প্লট করা যায়, যখন আমি বারের ফাংশনটিকে একাধিকবার কল করার চেষ্টা করেছি, তারা ওভারল্যাপ হয়ে গেছে এবং নীচের চিত্র হিসাবে দেখা গেছে সর্বোচ্চ মান লাল কেবল দেখা যায়। এক্স-অক্ষে খেজুর সহ আমি একাধিক বার কীভাবে প্লট করতে পারি?

এখনও পর্যন্ত, আমি এটি চেষ্টা করেছি:

import matplotlib.pyplot as plt
import datetime

x = [
    datetime.datetime(2011, 1, 4, 0, 0),
    datetime.datetime(2011, 1, 5, 0, 0),
    datetime.datetime(2011, 1, 6, 0, 0)
]
y = [4, 9, 2]
z = [1, 2, 3]
k = [11, 12, 13]

ax = plt.subplot(111)
ax.bar(x, y, width=0.5, color='b', align='center')
ax.bar(x, z, width=0.5, color='g', align='center')
ax.bar(x, k, width=0.5, color='r', align='center')
ax.xaxis_date()

plt.show()

আমি এটা বুজেছি:

এখানে চিত্র বর্ণনা লিখুন

ফলাফলগুলি এমন কিছু হওয়া উচিত, তবে তারিখগুলি এক্স-অক্ষে থাকে এবং বারগুলি একে অপরের পাশে থাকে:

এখানে চিত্র বর্ণনা লিখুন


আপনার x মানগুলি পরিবর্তন করতে হবে
জেটেরেস

4
আপনি কি বোঝাতে চেয়েছেন ? এক্স মানগুলি তারিখগুলি ...
জন স্মিথ

4
এগুলি কেবল ম্যাটপ্ল্লোলিব দ্বারা সমর্থনযোগ্য নয় কেন ?!
ihadanny

উত্তর:


115
import matplotlib.pyplot as plt
from matplotlib.dates import date2num
import datetime

x = [
    datetime.datetime(2011, 1, 4, 0, 0),
    datetime.datetime(2011, 1, 5, 0, 0),
    datetime.datetime(2011, 1, 6, 0, 0)
]
x = date2num(x)

y = [4, 9, 2]
z = [1, 2, 3]
k = [11, 12, 13]

ax = plt.subplot(111)
ax.bar(x-0.2, y, width=0.2, color='b', align='center')
ax.bar(x, z, width=0.2, color='g', align='center')
ax.bar(x+0.2, k, width=0.2, color='r', align='center')
ax.xaxis_date()

plt.show()

এখানে চিত্র বর্ণনা লিখুন

আমি জানি না "y মানগুলি ওভারল্যাপিং" এর অর্থ কী, নীচের কোডটি কী আপনার সমস্যার সমাধান করে?

ax = plt.subplot(111)
w = 0.3
ax.bar(x-w, y, width=w, color='b', align='center')
ax.bar(x, z, width=w, color='g', align='center')
ax.bar(x+w, k, width=w, color='r', align='center')
ax.xaxis_date()
ax.autoscale(tight=True)

plt.show()

এখানে চিত্র বর্ণনা লিখুন


ধন্যবাদ, তবে আমার যদি 3 টি বার থাকে তবে এটি দুর্দান্ত দেখাচ্ছে। আমি যখন 40 বারের মতো চেষ্টা করি তখন তা বিভ্রান্ত হয়। আপনি দয়া করে আরও সমাধানযোগ্য আপনার সমাধান আপডেট করতে পারেন?
জন স্মিথ

"মিসেস" সংজ্ঞায়িত করেন? এক্স লেবেলগুলিকে ওভারল্যাপিং ব্যবহার করে স্থির করা যেতে পারে autofmt_xdate()যা লেবেলগুলিকে স্বয়ংক্রিয়ভাবে ঘোরায়।
জন লিয়ন

সমস্যাটি এক্স লেবেলগুলিকে ওভারল্যাপ করে না, জিনিসটি হ'ল y মানগুলি ওভারল্যাপিং হয়। কিভাবে ঠিক হবে এটা ?
জন স্মিথ

এবং প্রস্থ = 0,2 বৃহত্তর সময়ের জন্য খুব ছোট। যদি আমি বড় মানগুলি ব্যবহার করি তবে আমি একই ফল পাই না।
জন স্মিথ

আরেকটি বিষয় হ'ল, শুরুর দিকে এবং শেষের ফাঁকা স্থানগুলি। স্পেসগুলি কীভাবে নির্মূল করা যায় এবং সরাসরি প্রথম তারিখটি শুরু করতে হয় এবং একইভাবে কোনও স্থান বা কম স্থান ছাড়াই শেষ তারিখটি শেষ করা যায়।
জন স্মিথ

61

তারিখগুলি এক্স-মান হিসাবে ব্যবহার করার ক্ষেত্রে সমস্যাটি হ'ল যদি আপনি নিজের দ্বিতীয় চিত্রের মতো বার চার্ট চান তবে সেগুলি ভুল হতে চলেছে। আপনি হয় একটি স্ট্যাক করা বার চার্ট (একে অপরের উপরে রঙ) বা তারিখ অনুসারে গ্রুপ (এক্স-অক্ষে একটি "নকল" তারিখ, মূলত কেবলমাত্র ডেটা পয়েন্টগুলি গোষ্ঠীকরণ) ব্যবহার করা উচিত।

import numpy as np
import matplotlib.pyplot as plt

N = 3
ind = np.arange(N)  # the x locations for the groups
width = 0.27       # the width of the bars

fig = plt.figure()
ax = fig.add_subplot(111)

yvals = [4, 9, 2]
rects1 = ax.bar(ind, yvals, width, color='r')
zvals = [1,2,3]
rects2 = ax.bar(ind+width, zvals, width, color='g')
kvals = [11,12,13]
rects3 = ax.bar(ind+width*2, kvals, width, color='b')

ax.set_ylabel('Scores')
ax.set_xticks(ind+width)
ax.set_xticklabels( ('2011-Jan-4', '2011-Jan-5', '2011-Jan-6') )
ax.legend( (rects1[0], rects2[0], rects3[0]), ('y', 'z', 'k') )

def autolabel(rects):
    for rect in rects:
        h = rect.get_height()
        ax.text(rect.get_x()+rect.get_width()/2., 1.05*h, '%d'%int(h),
                ha='center', va='bottom')

autolabel(rects1)
autolabel(rects2)
autolabel(rects3)

plt.show()

এখানে চিত্র বর্ণনা লিখুন


যদি আমি এক্স অক্ষগুলিতে 100 দিনের মতো দেখতে চাই তবে আপনি এটি কীভাবে ফিট করবেন?
জন স্মিথ

4
আপনি সহজেই তারিখ numpy এর সঙ্গে প্রয়োজনীয় উৎপন্ন পারে datetime64যেমন এক মাস মূল্য: np.arange('2012-02', '2012-03', dtype='datetime64[D]')। আপনার যদি এই ডেটা উপস্থাপনের সর্বোত্তম উপায় সম্পর্কে কঠোরভাবে চিন্তা করতে পারে তবে আপনার যদি 40 দিনের বেশি ডেটাসেট থাকে (অন্য মন্তব্য অনুসারে) 100 দিনেরও বেশি সময় ধরে রয়েছে।
জন লিয়ন

এছাড়াও, ax.xaxis_date () ব্যবহার করা খুব সুবিধাজনক কারণ এটি আপনার তারিখগুলিকে এক্স অক্ষের সাথে ফিট করে।
জন স্মিথ

4
আপনারা কেন প্রথমে যান না? আমি আপনাকে শিখতে সহায়তা করার চেষ্টা করছি, আপনার কোডটি আপনার জন্য না লিখে। আমি নিশ্চিত যে আপনি এটি দিয়ে করতে পারেন xaxis_dateতবে timedeltaপ্রতিটি সিরিজকে ওভারল্যাপিং বন্ধ করার জন্য আপনার তারিখের মানগুলি (যেমন কয়েক ঘন্টা ব্যবহার করে ) অফসেট করতে আমি যা লিখেছি তা আপনাকে খাপ খাইয়ে নিতে হবে। অন্য উত্তরটি কেবল এটি করে তবে আপনার পরে লেবেলগুলির সাথে কৌতুক করতে হবে।
জন লিয়ন

ঠিক আছে তবে আমি যখন এনপি.আরঞ্জ ('2012-02', '2012-03, dtype =' ডেটটাইম 64 [ডি] ') চালাচ্ছি তখন আমি এইটি পাচ্ছি:' স্ট্রিং 'এবং' এর জন্য অসমর্থিত অপারেন্ড টাইপ (গুলি) str '
জন স্মিথ

25

আমি জানি যে এটি প্রায় matplotlib, তবে ব্যবহার pandasএবং seabornআপনাকে অনেক সময় সাশ্রয় করতে পারে:

df = pd.DataFrame(zip(x*3, ["y"]*3+["z"]*3+["k"]*3, y+z+k), columns=["time", "kind", "data"])
plt.figure(figsize=(10, 6))
sns.barplot(x="time", hue="kind", y="data", data=df)
plt.show()

এখানে চিত্র বর্ণনা লিখুন


দুর্দান্ত উত্তর কিন্তু এক্স-অক্ষের কারণে এটি কিছুটা অসম্পূর্ণ। আপনি কি এটি আরও উপস্থাপন করতে পারেন?
স্পিনোর

আপনি অনুমান করতে পারেন, তাঁর পান্ডা এবং ম্যাটপ্ল্লোব দিয়েও করতে পারেন
ভিকি বি

18

অনুরূপ সমাধান অনুসন্ধান করার পরে এবং যথেষ্ট নমনীয় কিছু না পাওয়ার পরে, আমি এটির জন্য আমার নিজের ফাংশনটি লেখার সিদ্ধান্ত নিয়েছি। এটি আপনাকে গ্রুপ অনুযায়ী প্রতি বারে বার করার অনুমতি দেয় এবং একটি গ্রুপের প্রস্থতা এবং গ্রুপগুলির মধ্যে বারগুলির পৃথক প্রস্থ উভয়ই নির্দিষ্ট করে দেয়।

উপভোগ করুন:

from matplotlib import pyplot as plt


def bar_plot(ax, data, colors=None, total_width=0.8, single_width=1, legend=True):
    """Draws a bar plot with multiple bars per data point.

    Parameters
    ----------
    ax : matplotlib.pyplot.axis
        The axis we want to draw our plot on.

    data: dictionary
        A dictionary containing the data we want to plot. Keys are the names of the
        data, the items is a list of the values.

        Example:
        data = {
            "x":[1,2,3],
            "y":[1,2,3],
            "z":[1,2,3],
        }

    colors : array-like, optional
        A list of colors which are used for the bars. If None, the colors
        will be the standard matplotlib color cyle. (default: None)

    total_width : float, optional, default: 0.8
        The width of a bar group. 0.8 means that 80% of the x-axis is covered
        by bars and 20% will be spaces between the bars.

    single_width: float, optional, default: 1
        The relative width of a single bar within a group. 1 means the bars
        will touch eachother within a group, values less than 1 will make
        these bars thinner.

    legend: bool, optional, default: True
        If this is set to true, a legend will be added to the axis.
    """

    # Check if colors where provided, otherwhise use the default color cycle
    if colors is None:
        colors = plt.rcParams['axes.prop_cycle'].by_key()['color']

    # Number of bars per group
    n_bars = len(data)

    # The width of a single bar
    bar_width = total_width / n_bars

    # List containing handles for the drawn bars, used for the legend
    bars = []

    # Iterate over all data
    for i, (name, values) in enumerate(data.items()):
        # The offset in x direction of that bar
        x_offset = (i - n_bars / 2) * bar_width + bar_width / 2

        # Draw a bar for every value of that type
        for x, y in enumerate(values):
            bar = ax.bar(x + x_offset, y, width=bar_width * single_width, color=colors[i % len(colors)])

        # Add a handle to the last drawn bar, which we'll need for the legend
        bars.append(bar[0])

    # Draw legend if we need
    if legend:
        ax.legend(bars, data.keys())


if __name__ == "__main__":
    # Usage example:
    data = {
        "a": [1, 2, 3, 2, 1],
        "b": [2, 3, 4, 3, 1],
        "c": [3, 2, 1, 4, 2],
        "d": [5, 9, 2, 1, 8],
        "e": [1, 3, 2, 2, 3],
        "f": [4, 3, 1, 1, 4],
    }

    fig, ax = plt.subplots()
    bar_plot(ax, data, total_width=.8, single_width=.9)
    plt.show()

আউটপুট:

এখানে চিত্র বর্ণনা লিখুন


এক্স অক্ষে লেবেল যুক্ত করতে আমরা কীভাবে এটি পরিবর্তন করতে পারি? বারের প্রতিটি গ্রুপের মতো?
x89

xticksপ্লটটির পরিবর্তন করুন , যেমনplt.xticks(range(5), ["one", "two", "three", "four", "five"])
পাসকসচা

সুন্দর ফাংশন, খুব সহায়ক, ধন্যবাদ। কেবলমাত্র আমি পরিবর্তন করেছি যে আপনি বারপ্লট কলটিতে কেবলমাত্র ========================================================================================================================================================>
অ্যাড্রিয়ান টম্পকিনস

0

আমি এই সমাধানটি করেছি: আপনি যদি একটি চিত্রের মধ্যে একাধিক প্লট চান তবে পরবর্তী প্লটগুলি প্লট করার আগে আপনি matplotlib.pyplot.hold(True) অন্য প্লট যুক্ত করার অধিকার নির্ধারণ করেছেন তা নিশ্চিত করুন ।

এক্স অক্ষের তারিখের সময়কালের মানগুলি সম্পর্কে, বারগুলির সারিবদ্ধকরণ ব্যবহার করে একটি সমাধান আমার পক্ষে কাজ করে। আপনি যখন অন্য একটি বার প্লট তৈরি করেন matplotlib.pyplot.bar(), কেবল ব্যবহার করুন align='edge|center'এবং সেট করুন width='+|-distance'

আপনি যখন সমস্ত বার (প্লট) ঠিকঠাক করেন, আপনি বারগুলি সূক্ষ্ম দেখতে পাবেন।


দেখে মনে হচ্ছে matplotlib.pyplot.holdv2.0 থেকে অবহেলা করা হয়েছে, যেমন ডক্সে উল্লিখিত হয়েছে
ইঞ্জিনিয়ারিক্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.