Python & Pandas:当 Pandas 将直方图绘制到特定轴时的奇怪行为
Posted
技术标签:
【中文标题】Python & Pandas:当 Pandas 将直方图绘制到特定轴时的奇怪行为【英文标题】:Python & Pandas: Strange behavior when Pandas plot histogram to a specific ax 【发布时间】:2016-11-15 12:03:02 【问题描述】:我想将 pandas 直方图绘制到一个轴上,但这种行为真的很奇怪。我不知道这里出了什么问题。
fig1, ax1 = plt.subplots(figsize=(4,3))
fig2, ax2 = plt.subplots(figsize=(4,3))
fig3, ax3 = plt.subplots(figsize=(4,3))
# 1. This works
df['speed'].hist()
# 2. This doens't work
df['speed'].hist(ax=ax2)
# 3. This works
data = [1,2,3,5,6,2,3,4]
temp_df = pd.DataFrame(data)
temp_df.hist(ax=ax2)
jupyter notebook 返回的错误是:
AssertionError Traceback (most recent call last)
<ipython-input-46-d629de832772> in <module>()
7
8 # This doens't work
----> 9 df['speed'].hist(ax=ax2)
10
11 # # This works
D:\Anaconda2\lib\site-packages\pandas\tools\plotting.pyc in hist_series(self, by, ax, grid, xlabelsize, xrot, ylabelsize, yrot, figsize, bins, **kwds)
2953 ax = fig.gca()
2954 elif ax.get_figure() != fig:
-> 2955 raise AssertionError('passed axis not bound to passed figure')
2956 values = self.dropna().values
2957
AssertionError: passed axis not bound to passed figure
熊猫源代码在这里:
https://github.com/pydata/pandas/blob/d38ee272f3060cb884f21f9f7d212efc5f7656a8/pandas/tools/plotting.py#L2913
完全不知道我的代码有什么问题。
【问题讨论】:
我在尝试将 Pandas.hist() 图显示到 PyQt5 Ui 时也遇到了同样的问题。真令人沮丧。建议的解决方案均无效。 【参考方案1】:问题在于,pandas 通过使用gcf()
来获取“当前人物”来确定哪个是活动人物。当您连续创建多个图形时,“当前图形”是最后一个创建的图形。但是您正试图绘制到更早的一个,这会导致不匹配。
但是,正如您在链接到的源代码的第 2954 行所看到的,pandas 将寻找(未记录的)figure
参数。所以你可以通过df['speed'].hist(ax=ax2, figure=fig2)
让它工作。 pandas
源中的一条评论指出,这是“在绘图界面更加统一之前的修改”,所以我不会依赖它来做任何太重要的事情。
另一种解决方案是在您准备好使用之前不要创建新图。在上面的示例中,您只使用了图 2,因此无需创建其他示例。当然,这是一个人为的例子,但在现实生活中,如果你有这样的代码:
fig1, ax1 = plt.subplots(figsize=(4,3))
fig2, ax2 = plt.subplots(figsize=(4,3))
fig3, ax3 = plt.subplots(figsize=(4,3))
something.hist(ax=ax1)
something.hist(ax=ax2)
something.hist(ax=ax3)
你可以改成这样:
fig1, ax1 = plt.subplots(figsize=(4,3))
something.hist(ax=ax1)
fig2, ax2 = plt.subplots(figsize=(4,3))
something.hist(ax=ax2)
fig3, ax3 = plt.subplots(figsize=(4,3))
something.hist(ax=ax3)
也就是说,将绘图代码的每个部分放在为该绘图创建图形的代码之后。
【讨论】:
我也遇到了这个问题,但是我没看明白答案:pandas确定哪个是活动图第二种情况,大佬指ax=ax2
但为什么还不够?如果您输入一个简单的plot
,而不是hist
,它就可以工作。为什么这两个功能有区别?谢谢
@SPS:为什么?我不知道。使用未记录的figure
参数的黑客似乎只存在于hist
中。为什么会这样,我不知道。
谢谢!!知道您可以将图形传递给熊猫图,我非常有用【参考方案2】:
在尝试将 Pandas 直方图绘制到 PyQt5 小部件(来自使用 Qt Creator 创建的 UI)中时,我遇到了类似的问题。
代码看起来像这样:
from PyQt5 import QtWidgets
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvas
import numpy as np
import pandas as pd
class MplWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.canvas = FigureCanvas(Figure())
vertical_layout = QtWidgets.QVBoxLayout()
vertical_layout.addWidget(self.canvas)
self.canvas.axes = self.canvas.figure.add_subplot(111)
self.setLayout(vertical_layout)
index1 = np.random.rand(10000)
data1 = np.random.gamma(2, 2, 10000)
s1 = pd.Series(data1, index=index1)
MplWidget_object = MplWidget_FROM_MY_GUI
s1.hist(ax=MplWidget_object.canvas.axes) # This would throw an error.
pd.DataFrame(s1).hist(ax=MplWidget_object.canvas.axes) # This Works!!!
我设法通过将我的 pandas.Series 转换为 Dataframe 来使其工作(两行代码)
【讨论】:
以上是关于Python & Pandas:当 Pandas 将直方图绘制到特定轴时的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章
扁平化(不规则)Python 中关于 Pandas Dataframes 的列表列表