10

我无法在同一个图上显示条形图和折线图。示例代码:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

Df = pd.DataFrame(data=np.random.randn(10,4), index=pd.DatetimeIndex(start='2005', freq='M', periods=10), columns=['A','B','C','D'])

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

Df[['A','B']].plot(kind='bar', ax=ax)
Df[['C','D']].plot(ax=ax, color=['r', 'c'])
4

4 回答 4

13

你也可以试试这个:

fig = plt.figure()
ax = DF['A','B'].plot(kind="bar");plt.xticks(rotation=0)
ax2 = ax.twinx()
ax2.plot(ax.get_xticks(),DF['C','D'],marker='o')
于 2014-03-05T21:19:58.500 回答
2

问题是 pandas 条形图函数将日期视为一个分类变量,其中每个日期都被认为是一个唯一的类别,因此 x 轴单位设置为从 0 开始的整数(如未分配时的默认 DataFrame 索引)。

pandas 线图使用与 DatetimeIndex 对应的 x 轴单位,其中 0 位于 1970 年 1 月,整数计算从那时起的周期数(本例中为月)。那么让我们来看看在这种特殊情况下会发生什么:

import numpy as np     # v 1.19.2
import pandas as pd    # v 1.1.3

# Create random data
rng = np.random.default_rng(seed=1) # random number generator
df = pd.DataFrame(data=rng.normal(size=(10,4)),
                  index=pd.date_range(start='2005', freq='M', periods=10),
                  columns=['A','B','C','D'])

# Create a pandas bar chart overlaid with a pandas line plot using the same
# Axes: note that seeing as I do not set any variable for x, df.index is used
# by default, which is usually what we want when dealing with a dataset
# containing a time series
ax = df.plot.bar(y=['A','B'], figsize=(9,5))
df.plot(y=['C','D'], color=['tab:green', 'tab:red'], ax=ax);

pandas_bar_line_wrongx

酒吧无处可寻。如果您检查正在使用哪些 x 刻度,您会看到 1 月放置的单个主要刻度420之后是其他月份的这些次要刻度:

ax.get_xticks(minor=True)
# [421, 422, 423, 424, 425, 426, 427, 428, 429]

这是因为自 1970 年以来有 35 年 * 12 个月,编号从 0 开始,因此 2005 年 1 月落在 420 上。这解释了为什么我们看不到条形。如果您将 x 轴限制更改为从零开始,您会得到以下结果:

ax = df.plot.bar(y=['A','B'], figsize=(9,5))
df.plot(y=['C','D'], color=['tab:green', 'tab:red'], ax=ax)
ax.set_xlim(0);

pandas_bar_line_setxlim

从 1970 年 1 月开始,这些条向左压扁。这个问题可以通过设置use_index=False线图函数来解决,使线也从 0 开始:

ax = df.plot.bar(y=['A','B'], figsize=(9,5))
df.plot(y=['C','D'], color=['tab:green', 'tab:red'], ax=ax, use_index=False)
ax.set_xticklabels(df.index.strftime('%b'), rotation=0, ha='center');

# # Optional: move legend to new position
# import matplotlib.pyplot as plt    # v 3.3.2
# ax.legend().remove()
# plt.gcf().legend(loc=(0.08, 0.14));

pandas_bar_line

如果您想要更高级的刻度标签格式,您可以查看与此示例兼容的此问题的答案。如果您需要matplotlib.dates模块中的刻度定位器和格式化程序提供的更灵活/自动的刻度标签格式,最简单的方法是使用 matplotlib 创建绘图,就像在这个答案中一样。

于 2021-01-09T22:38:19.690 回答
2

我也想知道,但是所有现有答案都不是为了在同一个图上显示条形图和折线图,而是在不同的轴上显示。

所以我自己寻找答案并找到了一个有效的例子——在同一张图表上将 Pandas DataFrame 绘制为 Bar 和 Line。我可以确认它有效

让我感到困惑的是,几乎相同的代码在那里工作,在这里不起作用。即,我复制了 OP 的代码并且可以验证它没有按预期工作

我唯一能想到的是将索引列添加到Df[['A','B']]and Df[['C','D']],但我不知道如何,因为索引列没有我要添加的名称。

今天,我意识到即使我可以让它工作,真正的问题是Df[['A','B']]给出了一个分组(集群)条形图,但不支持分组(集群)折线图。

于 2015-12-31T17:22:41.117 回答
0

你可以在同一个图上做类似的事情:

In [4]: Df = pd.DataFrame(data=np.random.randn(10,4), index=pd.DatetimeIndex(start='2005', freq='M', periods=10), columns=['A','B','C','D'])

In [5]: fig, ax = plt.subplots(2, 1) # you can pass sharex=True, sharey=True if you want to share axes.

In [6]: Df[['A','B']].plot(kind='bar', ax=ax[0])
Out[6]: <matplotlib.axes.AxesSubplot at 0x10cf011d0>

In [7]: Df[['C','D']].plot(color=['r', 'c'], ax=ax[1])
Out[7]: <matplotlib.axes.AxesSubplot at 0x10a656ed0>
于 2013-11-12T23:15:14.093 回答