Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python matplotlib多条_Python_Matplotlib - Fatal编程技术网

Python matplotlib多条

Python matplotlib多条,python,matplotlib,Python,Matplotlib,如何在matplotlib中绘制多个条形图,当我多次尝试调用条形图函数时,它们重叠,如下图所示,只能看到最大值红色。 如何在x轴上绘制带有日期的多个条形图 到目前为止,我尝试了以下方法: 导入matplotlib.pyplot作为plt 导入日期时间 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]

如何在matplotlib中绘制多个条形图,当我多次尝试调用条形图函数时,它们重叠,如下图所示,只能看到最大值红色。 如何在x轴上绘制带有日期的多个条形图

到目前为止,我尝试了以下方法:

导入matplotlib.pyplot作为plt
导入日期时间
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.子批次(111)
ax.条(x,y,宽度=0.5,颜色='b',对齐='center')
ax.条(x,z,宽度=0.5,颜色='g',对齐='center')
最大条(x,k,宽度=0.5,颜色=r',对齐=center')
ax.xaxis_日期()
plt.show()
我明白了:

结果应该是类似的,但日期在x轴上,条形图彼此相邻:


使用日期作为x值的问题在于,如果您想要第二张图片中的条形图,那么它们将是错误的。您应该使用堆叠条形图(颜色相互重叠)或按日期分组(x轴上的“假”日期,基本上只是对数据点进行分组)

我不知道“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()

我做了这个解决方案:如果您想在一个图形中绘制多个绘图,请确保在绘制下一个绘图之前,已将matplotlib.pyplot.hold(True) 可以添加另一个绘图

关于X轴上的日期时间值,使用条对齐的解决方案适合我。使用
matplotlib.pyplot.bar()
创建另一个条形图时,只需使用
align='edge | center'
并设置
width='+|-distance'


当您正确设置所有条形图(绘图)时,您将看到条形图。我知道这是关于
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()

在寻找类似的解决方案,但没有找到足够灵活的解决方案后,我决定为其编写自己的函数。它允许您在每个组中拥有任意数量的钢筋,并指定组的宽度以及组内钢筋的单个宽度

享受:

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()

输出:


不要使用matplotlib执行此操作要复杂得多。最好使用seaborn:

在这里:

您需要更改x值,这是什么意思?X值是日期…为什么matplotlib不简单地支持它?!谢谢,但是如果我有三根,看起来不错。当我尝试像40酒吧,它搞砸了。你能更新你的解决方案使其更具可扩展性吗?定义“混乱”?可以使用自动旋转标签的
autofmt_xdate()
来修复X标签重叠。问题不在于X标签重叠,而是y值也重叠。如何修复?而且宽度=0,2对于大的时间跨度来说太小了。如果我使用更大的值,我不会得到相同的结果。另一件事是,开头和结尾的空格。如何消除空格,直接开始第一个日期,同样结束最后一个日期,没有任何空格或更少的空格。如果我想在x轴上显示100天,您如何调整它们?您可以使用numpy的
datetime64
:例如,一个月的值:
np.arange轻松生成所需的日期('2012-02'、'2012-03',dtype='datetime64[D]')
。如果您有40个数据集(根据另一条评论)跨越100天,您可能需要更仔细地考虑表示此数据的最佳方式。此外,使用ax.xaxis_date()是非常有优势的,因为它可以将您的日期与x轴相匹配。为什么您不先试一下呢?我只是想帮助您学习,而不是为您编写代码。我相信您可以使用
xaxis\u date
来实现这一点,但您需要调整我编写的内容,以抵消您的日期值(例如,使用
timedelta
以小时为单位)另一个答案就是这样做的,但是你可能需要在之后处理标签。好的,但是当我运行np.arange('2012-02','2012-03,dtype='datetime64[D])时,我得到的是:不支持的操作数类型对于-:“str”和“str”回答得很好,但由于x轴的原因,它有点不完整。你能让它更形象吗?我想,你也可以用pandas和matplotlib来完成它。你可以用以下格式来完成:
x=[datetime.datetime.strtime(d),%Y-%m-%d”)代表x中的d]。sort()
不要忘了
导入seaborn as sns
;)我们如何修改此项以将标签添加到x轴?与每组条形图一样?更改绘图的
xticks
,例如
plt.xticks(范围(5),[“一”、“二”、“三”、“四”、“五”)
功能不错,非常有用,谢谢。我唯一改变的是,我认为图例更容易,只要在barplot调用中放入label=data.keys[I],然后就不需要构建条形图列表。它看起来像
matplotlib.pyplot.hold
从v2.0开始就被弃用了,如下所示
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()
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()