我试图把条形图和线条图绘制成一个单一的图形,并且由于其良好的格式化功能,我倾向于使用seaborn。然而,当我做df1.plot(kind='bar',...)和df1.plot(kind='line',..., secondary_y=True)之后,我得到了如下类似的结果,即没有线条图,但是没有错误。
import seaborn as sns
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Sample dataframe.
df1 = pd.DataFrame({'date':pd.date_range(datetime(2020,1,1), periods=699).tolist(), 'amount':range(1,700), 'balance':np.cumsum(range(1,700))})
df1.loc[:, 'month'] = df1['date'].dt.to_period("M")
df1.loc[:, 'month_str'] = df1['date'].dt.year.astype(str) + '-' + df1['date'].dt.month.astype(str)
df1.loc[:, 'month_dt'] = pd.to_datetime(df1.month.dt.year*10000+df1.month.dt.month*100+1,format='%Y%m%d')
# Case-1: This doesn't work.
df2 = df1.groupby(['month']).agg({'amount':'sum','balance':'sum'})
sns.barplot(x='month', y='amount', data=df2.reset_index(), palette="Blues_d")
ax2 = plt.twinx()
sns.lineplot(x='month', y='balance', data=df2.reset_index(), color='red', markers=True, ax=ax2)
# Case-2: This doesn't work (as intended, if months grow they will not auto-adjust max numbers to show and not sorted).
df2 = df1.groupby(['month_str']).agg({'amount':'sum','balance':'sum'})
sns.barplot(x='month_str', y='amount', data=df2.reset_index(), palette="Blues_d")
ax2 = plt.twinx()
sns.lineplot(x='month_str', y='balance', data=df2.reset_index(), color='red', markers=True, ax=ax2)
# Case-3: This doesn't work either.
df2 = df1.groupby(['month_dt']).agg({'amount':'sum','balance':'sum'})
sns.barplot(x='month_dt', y='amount', data=df2.reset_index(), palette="Blues_d")
ax2 = plt.twinx()
sns.lineplot(x='month_dt', y='balance', data=df2.reset_index(), color='red', markers=True, ax=ax2)案例-1:

Traceback (most recent call last):
File "C:\...\lib\site-packages\seaborn\_decorators.py", line 46, in inner_f
return f(**kwargs)
File "C:\...\lib\site-packages\seaborn\relational.py", line 703, in lineplot
p.plot(ax, kwargs)
File "C:\...\lib\site-packages\seaborn\relational.py", line 529, in plot
line, = ax.plot(x, y, **kws)
File "C:\...\lib\site-packages\matplotlib\axes\_axes.py", line 1745, in plot
self.add_line(line)
File "C:\...\lib\site-packages\matplotlib\axes\_base.py", line 1964, in add_line
self._update_line_limits(line)
File "C:\...\lib\site-packages\matplotlib\axes\_base.py", line 1986, in _update_line_limits
path = line.get_path()
File "C:\...\lib\site-packages\matplotlib\lines.py", line 1011, in get_path
self.recache()
File "C:\...\lib\site-packages\matplotlib\lines.py", line 653, in recache
x = _to_unmasked_float_array(xconv).ravel()
File "C:\...\lib\site-packages\matplotlib\cbook\__init__.py", line 1289, in _to_unmasked_float_array
return np.asarray(x, float)
File "C:\...\lib\site-packages\numpy\core\_asarray.py", line 83, in asarray
return array(a, dtype, copy=False, order=order)
TypeError: float() argument must be a string or a number, not 'Period'Case-2:

Case-3:

发布于 2021-04-29 21:33:25
您可以构建虚拟x轴,并在构建绘图之后用月份数据替换值:
fig, ax = plt.subplots()
df2 = df1.groupby(['month']).agg({'amount':'sum','balance':'sum'})
# helper axis
data = df2.reset_index()
data['xaxis'] = range(len(data))
sns.barplot(x='xaxis', y='amount', data=data, palette="Blues_d", ax=ax)
ax2 = ax.twinx()
sns.lineplot(x='xaxis', y='balance', data=data, color='red', markers=True, ax=ax2)
# replace helper axis with actual data
ax.set_xticklabels(data['month'].values, rotation = 45, ha="right")

发布于 2022-01-07 01:32:26
您不需要创建虚拟x轴。尝试以下代码:
import seaborn as sns
import pandas as pd
import numpy as np
# Sample dataframe.
df1 = pd.DataFrame({'date':pd.date_range(pd.datetime(2020,1,1), periods=699).tolist(), 'amount':range(1,700), 'balance':np.cumsum(range(1,700))})
df1.loc[:, 'month'] = df1['date'].dt.to_period("M")
df2 = df1.groupby(['month']).agg({'amount':'sum','balance':'sum'})
g = sns.barplot(x='month', y='amount', data=df2.reset_index(), palette="Blues_d")
g.set_xticklabels(g.get_xticklabels(), rotation=90)
sns.lineplot(x=range(len(df2.reset_index())), y='balance', data=df2.reset_index(), color='red', markers=True, ax=g.twinx())

https://stackoverflow.com/questions/67323635
复制相似问题