【问题标题】:Combine Binned barplot with lineplot结合分箱条形图和线图
【发布时间】:2023-02-07 03:11:36
【问题描述】:

我想在同一个图上表示两个数据集,一个作为一条线,一个作为分箱条形图。我可以单独做每一个:

tobar = pd.melt(pd.DataFrame(np.random.randn(1000).cumsum()))
tobar["bins"] = pd.qcut(tobar.index, 20)

bp = sns.barplot(data=tobar, x="bins", y="value")

toline = pd.melt(pd.DataFrame(np.random.randn(1000).cumsum()))

lp = sns.lineplot(data=toline, x=toline.index, y="value")

但是当我尝试将它们组合在一起时,x 轴当然会弄乱:

fig, ax = plt.subplots()
ax2 = ax.twinx()
bp = sns.barplot(data=tobar, x="bins", y="value", ax=ax)
lp = sns.lineplot(data=toline, x=toline.index, y="value", ax=ax2)
bp.set(xlabel=None)

我似乎也无法摆脱垃圾箱标签。

我怎样才能在一个地块上获得这两个信息?

【问题讨论】:

  • 将这两个图绘制在同一个图中是否有意义?我的意思是 lineplot 从第一条记录到最后一条记录画一条线,而不考虑 y 值。相比之下,barplot 将您的数据重新组织成组。知道它不共享相同的 x 轴,我们应该如何解释该图?
  • @Corralien 因为我将箱子用作条形图的 x 轴,所以数据仍然是从头到尾绘制的。此处的条形图用作一种高度平滑的线图,但对于我正在处理的数据,将两条线放在一起会使情节非常拥​​挤且难以阅读

标签: python matplotlib seaborn bar-chart line-plot


【解决方案1】:
  • answer 解释了为什么最好使用 matplotlib.axes.Axes.bar 而不是 sns.barplotpandas.DataFrame.bar 来绘制条形图。
    • 简而言之,xtick位置对应标签的实际数值,而seabornpandasxticks是0索引,不对应数值。
  • answer 展示了如何添加栏标签。
  • ax2 = ax.twinx() 可根据需要用于线图
  • python 3.11pandas 1.5.2matplotlib 3.6.2seaborn 0.12.1 中测试

导入和数据框

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

# test data
np.random.seed(2022)
df = pd.melt(pd.DataFrame(np.random.randn(1000).cumsum()))

# create the bins
df["bins"] = pd.qcut(df.index, 20)

# add a column for the mid point of the interval
df['mid'] = df.bins.apply(lambda row: row.mid.round().astype(int))

# pivot the dataframe to calculate the mean of each interval
pt = df.pivot_table(index='mid', values='value', aggfunc='mean').reset_index()

地块 1

# create the figure
fig, ax = plt.subplots(figsize=(30, 7))

# add a horizontal line at y=0 
ax.axhline(0, color='black')

# add the bar plot
ax.bar(data=pt, x='mid', height='value', width=4, alpha=0.5)

# set the labels on the xticks - if desired
ax.set_xticks(ticks=pt.mid, labels=pt.mid)

# add the intervals as labels on the bars - if desired
ax.bar_label(ax.containers[0], labels=df.bins.unique(), weight='bold')

# add the line plot
_ = sns.lineplot(data=df, x=df.index, y="value", ax=ax, color='tab:orange')

地块 2

fig, ax = plt.subplots(figsize=(30, 7))

ax.axhline(0, color='black')

ax.bar(data=pt, x='mid', height='value', width=4, alpha=0.5)

ax.set_xticks(ticks=pt.mid, labels=df.bins.unique(), rotation=45)

ax.bar_label(ax.containers[0], weight='bold')

_ = sns.lineplot(data=df, x=df.index, y="value", ax=ax, color='tab:orange')

地块 3

  • 条宽为区间宽度
fig, ax = plt.subplots(figsize=(30, 7))

ax.axhline(0, color='black')

ax.bar(data=pt, x='mid', height='value', width=50, alpha=0.5, ec='k')

ax.set_xticks(ticks=pt.mid, labels=df.bins.unique(), rotation=45)

ax.bar_label(ax.containers[0], weight='bold')

_ = sns.lineplot(data=df, x=df.index, y="value", ax=ax, color='tab:orange')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 2013-06-29
    • 2023-03-22
    • 1970-01-01
    • 2016-12-13
    • 2015-10-15
    相关资源
    最近更新 更多