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