पायथन मैटलपोटलिब कई बार


94

मैटप्लोटलिब में कई बार प्लॉट कैसे करें, जब मैंने बार फ़ंक्शन को कई बार कॉल करने की कोशिश की, तो वे ओवरलैप करते हैं और नीचे दिए गए आंकड़े के अनुसार उच्चतम मूल्य लाल को ही देखा जा सकता है। मैं एक्स-एक्सिस पर तारीखों के साथ कई सलाखों की साजिश कैसे कर सकता हूं?

अब तक, मैंने यह कोशिश की:

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 मान बदलने की आवश्यकता है
jterrace

2
आपका क्या अर्थ है ? एक्स मान तारीखें हैं ...
जॉन स्मिथ

4
क्यों यह बस matplotlib द्वारा समर्थित नहीं है ?!
इदानी

जवाबों:


118
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(), जो लेबल को ऑटो-रोटेट करता है।
जॉन लियोन

समस्या एक्स लेबल को ओवरलैपिंग नहीं है, बात यह है कि वाई मान भी अतिव्यापी हैं। इसे कैसे जोड़ेंगे ?
जॉन स्मिथ

और भी चौड़ाई = 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 दिनों की तरह दिखाना चाहता हूं, तो आप उन्हें कैसे फिट करते हैं?
जॉन स्मिथ

1
आप आसानी से अंक के साथ आवश्यक तिथियां उत्पन्न कर सकते हैं datetime64: जैसे एक महीने का मूल्य np.arange('2012-02', '2012-03', dtype='datetime64[D]'):। यदि आपके पास 40 डेटासेट (एक अन्य टिप्पणी के अनुसार) 100 से अधिक दिनों का है, तो आपको इस डेटा का प्रतिनिधित्व करने के सबसे अच्छे तरीके के बारे में अधिक सोचने की आवश्यकता हो सकती है।
जॉन लीयोन

और यह भी, ax.xaxis_date () का उपयोग करना बहुत फायदे हैं, क्योंकि यह आपकी तारीखों को एक्स अक्षों में फिट करता है।
जॉन स्मिथ

3
आपके पास पहले क्यों नहीं है? मैं आपको सीखने में मदद करने की कोशिश कर रहा हूं, न कि आपके लिए अपना कोड लिखूं। मुझे यकीन है कि आप इसे कर सकते हैं, xaxis_dateलेकिन आपको timedeltaओवरलैपिंग को रोकने के लिए प्रत्येक श्रृंखला के लिए अपनी तारीख के मूल्यों (जैसे कई घंटों का उपयोग करके ) को ऑफसेट करने के लिए लिखे गए अनुकूलन की आवश्यकता होगी । अन्य उत्तर बस यही करता है, लेकिन आपको बाद में लेबल के साथ मिलाना पड़ सकता है।
जॉन लियोन

ठीक है, लेकिन जब मैं np.arange ('2012-02', '2012-03, dtype =' datetime64 [D] ') चलाता हूं, तो मुझे यह मिल रहा है: असमर्थित ऑपरेंड प्रकार (ओं) के लिए -:' str 'और' 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()

यहां छवि विवरण दर्ज करें


महान जवाब लेकिन यह एक्स-अक्ष के कारण कुछ अधूरा है। क्या आप इसे अधिक प्रस्तुत करने योग्य बना सकते हैं?
स्पिनर 8

आप, मैं पंडों और मत्तप्लोटिब के साथ भी कर सकता हूं
विकी बी

19

इसी तरह के समाधान की तलाश करने और पर्याप्त रूप से कुछ भी लचीला नहीं खोजने के बाद, मैंने इसके लिए अपना खुद का फ़ंक्शन लिखने का फैसला किया। यह आपको अपनी इच्छानुसार प्रति समूह में कई बार होने की अनुमति देता है और एक समूह की चौड़ाई के साथ-साथ समूहों के भीतर सलाखों की व्यक्तिगत चौड़ाई दोनों को निर्दिष्ट करता है।

का आनंद लें:

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"])
pascscha

अच्छा कार्य, बहुत उपयोगी, धन्यवाद। केवल एक चीज जो मैंने बदली है वह यह है कि मुझे लगता है कि किंवदंती आसान है यदि आप सिर्फ लेबल = data.keys [i] को बारप्लॉट कॉल में डालते हैं और फिर आपको बार सूची बनाने की आवश्यकता नहीं है।
एड्रियन टोमकिन्स

0

मैंने यह समाधान किया है: यदि आप एक से अधिक भूखंडों को एक आंकड़े में चाहते हैं, तो अगले भूखंडों की साजिश करने से पहले सुनिश्चित करें कि आपने matplotlib.pyplot.hold(True) दूसरे भूखंडों को जोड़ने में सक्षम हैं।

एक्स अक्ष पर डेटाटाइम मानों के संबंध में, बार के संरेखण का उपयोग करने वाला एक समाधान मेरे लिए काम करता है। जब आप के साथ एक और बार प्लॉट बनाते हैं matplotlib.pyplot.bar(), तो बस उपयोग करें align='edge|center'और सेट करें width='+|-distance'

जब आप सभी बार (भूखंड) सही सेट करते हैं, तो आप सलाखों को ठीक देखेंगे।


ऐसा लगता है कि matplotlib.pyplot.holdv2.0 के बाद से बहिष्कृत कर दिया गया है, के रूप में उल्लेख किया डॉक्स
engineervix
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.