在Matplotlib上表示大量绘制条形图的解决方案?

2024-06-10 15:57:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在努力规划一个价值非常小和非常大的酒吧。我试着用两个y轴绘制图表

但是,输出无法表示数据,并且不同y轴上的绿色列无法与其他数据进行比较。是否有一种解决方案来改变绿色栏以显示2015-2019年的数据,2020年的数据表示在第二个y轴上?还是有其他好的解决办法

请帮帮我

守则:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

dict_ = {'date': [pd.Timestamp('20150720'),pd.Timestamp('20160720'),pd.Timestamp('20170720'),pd.Timestamp('20180720'),pd.Timestamp('20190720'),pd.Timestamp('20200720')],
            'BKNG': [15.22, 6.36, 5.05, 5, 9.3641, -3],
            'MCD' : [25.22, 11.36, 7.05, 9, 8.3641, -6],
            'YUM' : [52.22, 21.36, 25.05, 26, 21.3641, -1000]
    
}

df = pd.DataFrame(dict_)
df['date'] = df['date'].dt.year
df.set_index('date',inplace=True)

fig1,ax = plt.subplots(figsize=(10,6))

ax.bar(df.index+0.0, df['BKNG'],width=0.1,label='BKNG')
ax.bar(df.index+0.1, df['MCD'],width=0.1,label='MCD')
plt.grid(True)
plt.legend()
plt.xlabel('date')
plt.ylabel('value')
plt.title('ROE')

ax2 = ax.twinx()
ax2.bar(df.index+0.2, df['YUM'],width=0.1,label='YUM', color='g')
plt.legend(loc=3)
plt.ylabel('YUM')

output


Tags: 数据importdfdateindexasbarplt
2条回答

如果要使用第一个y轴显示2019年之前的数据,使用第二个y轴显示2020年之前的数据,可以使用:

fig1,ax = plt.subplots(figsize=(10,6))

ax.bar(df.index[:-1]+0.0, df.iloc[:-1,0],width=0.1,label='BKNG')
ax.bar(df.index[:-1]+0.1, df.iloc[:-1,1],width=0.1,label='MCD')
ax.bar(df.index[:-1]+0.2, df.iloc[:-1,2],width=0.1,label='YUM')
plt.grid(True)
plt.legend()
plt.xlabel('date')
plt.ylabel('value')
plt.title('ROE')

ax2 = ax.twinx()
ax2.bar(df.index[-1]+0.0, df.iloc[-1,0],width=0.1,label='BKNG')
ax2.bar(df.index[-1]+0.1, df.iloc[-1,1],width=0.1,label='MCD')
ax2.bar(df.index[-1]+0.2, df.iloc[-1,2],width=0.1,label='YUM', color='green')
ax2.set_ylim((-1001,10))
ax2.set_yscale('symlog')

enter image description here 或者,我会对所有数据使用symlog,如下所示:

fig1,ax = plt.subplots(figsize=(10,6))

ax.bar(df.index+0.0, df.iloc[:,0],width=0.1,label='BKNG')
ax.bar(df.index+0.1, df.iloc[:,1],width=0.1,label='MCD')
ax.bar(df.index+0.2, df.iloc[:,2],width=0.1,label='YUM')
plt.grid(True)
ax.set_yscale('symlog')
plt.legend()
plt.xlabel('date')
plt.ylabel('value')
plt.title('ROE')

enter image description here

您可能会看到缩放数据的建议,这将丢失原始度量单位。在很多情况下,这很好,但在商业环境中,它有时是不可解释的

如果要保留度量单位,可以创建两个图表,修改轴范围,然后使用一些对角线指示轴中存在间隙。这是一种非常传统的方法,用于绘制具有如此大差距的值,并且大多数人都可以理解

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

dict_ = {'date': [pd.Timestamp('20150720'),pd.Timestamp('20160720'),pd.Timestamp('20170720'),pd.Timestamp('20180720'),pd.Timestamp('20190720'),pd.Timestamp('20200720')],
            'BKNG': [15.22, 6.36, 5.05, 5, 9.3641, -3],
            'MCD' : [25.22, 11.36, 7.05, 9, 8.3641, -6],
            'YUM' : [52.22, 21.36, 25.05, 26, 21.3641, -1000]
    
}

df = pd.DataFrame(dict_)
df['date'] = df['date'].dt.year

df = df.set_index('date').stack().reset_index()
df.columns = ['date','ticker','value']


f, ax = plt.subplots(2, 1, sharex=True, figsize=(10,6))
f.tight_layout()
# plot the same data on both axes
sns.barplot(x='date',y='value',hue='ticker',data=df, ax=ax[0], )
ax[0].set_ylim(-100,100)
sns.barplot(x='date',y='value',hue='ticker',data=df, ax=ax[1])
ax[1].set_ylim(-1050,-900)

ax[0].spines['bottom'].set_visible(False)
ax[0].set(xlabel='', ylabel='')
ax[0].spines['top'].set_visible(False)
ax[0].xaxis.tick_top()
ax[0].tick_params(labeltop='off')  # don't put tick labels at the top
ax[1].xaxis.tick_bottom()
ax[1].legend([],[], frameon=False)
d = .01  # how big to make the diagonal lines in axes coordinates
# arguments to pass to plot, just so we don't keep repeating them
kwargs = dict(transform=ax[0].transAxes, color='k', clip_on=False)
ax[0].plot((-d, +d), (-d, +d), **kwargs)        # top-left diagonal
ax[0].plot((1 - d, 1 + d), (-d, +d), **kwargs)  # top-right diagonal

kwargs.update(transform=ax[1].transAxes)  # switch to the bottom axes
ax[1].plot((-d, +d), (1 - d, 1 + d), **kwargs)  # bottom-left diagonal
ax[1].plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs)  # bottom-right diagonal

# What's cool about this is that now if we vary the distance between
# ax and ax2 via f.subplots_adjust(hspace=...) or plt.subplot_tool(),
# the diagonal lines will move accordingly, and stay right at the tips
# of the spines they are 'breaking'

plt.show()

enter image description here

相关问题 更多 >