【问题标题】:plotting a line graph on a count plot with a separate y-axis on the right side在计数图上绘制折线图,​​右侧有单独的 y 轴
【发布时间】:2016-10-28 23:20:58
【问题描述】:

我创建了一个类似于我正在使用的虚拟数据框。 数据框由票价、客舱类型和生存(1 为活着,0 = 死亡)组成。

第一个图通过 factorplot 创建了许多图,每个图代表 Cabin 类型。 x 轴由票价表示,而 Y 轴只是对该票价的发生次数的计数。

然后我所做的是通过 [Cabin, Fare] 的 groupby 创建另一个系列,然后继续取生存平均值以获得每个舱位和票价价格的生存率。

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


df = pd.DataFrame(dict(
        Fare=[20, 10, 30, 40, 40, 10, 20, 30, 40 ,30, 20, 30, 30],
        Cabin=list('AAABCDBDCDDDC'),
        Survived=[1, 0, 0, 0 ,0 ,1 ,1 ,0 ,1 ,1 , 0, 1, 1]
    ))

g =sns.factorplot(x='Fare', col='Cabin', kind='count', data=df,
                  col_wrap=3, size=3, aspect=1.3,  palette='muted')

plt.show()

x =df.groupby(['Cabin','Fare']).Survived.mean()

我想做的是,在上面的计数图上绘制一个线图,(所以 x 轴是相同的,每个图仍然由 Cabin 类型表示),但我想要 y-轴是我们在上面的代码中使用 groupby 系列 x 计算的生存平均值,输出时将是下面的第三列。

Cabin  Fare
A      10      0.000000
       20      1.000000
       30      0.000000
B      20      1.000000
       40      0.000000
C      30      1.000000
       40      0.500000
D      10      1.000000
       20      0.000000
       30      0.666667

折线图的y轴应该在右边,我想要的范围是[0, .20, .40, .60, .80, 1.0, 1.2]

我浏览了 seaborn 文档一段时间,但不知道如何正确执行此操作。

我想要的输出看起来像这张图片。对不起,我的文字看起来很糟糕,我不知道如何很好地使用油漆。所以刻度和数字位于每个图表的右侧。线图将通过每个 x,y 点的点连接。所以对于小屋 A,第一个 x,y 点是 (10,0),其中 0 对应于右侧 y 轴。第二个点是 (20,1) 等等。

【问题讨论】:

  • 我不确定您希望它是什么样子。你能在你认为应该有线条的地方画出图像吗?
  • 嗨 piRSquared。有没有办法通过这个网站上的工具来绘制图表?还是我需要使用 MS 油漆?由于我对它不太熟悉,所以我将不得不使用 MS Paint。
  • 好的,我使用了 MS Paint 并添加了我想要的输出。我希望我的补充很清楚。
  • 那是完美的。我稍后会看看它。除非别人比我强。

标签: python pandas matplotlib seaborn


【解决方案1】:

数据操作:

计算频率计数:

df_counts = pd.crosstab(df['Fare'], df['Cabin'])

计算意味着跨组并将其解栈以获得DFNan's 保持原样,不会被零替换以显示折线图中的中断,否则它们将是连续的,这在这里没有多大意义。

df_means = df.groupby(['Cabin','Fare']).Survived.mean().unstack().T

将 x 轴标签准备为字符串:

df_counts.index = df_counts.index.astype(str)
df_means.index = df_means.index.astype(str)

绘图:

fig, ax = plt.subplots(1, 4, figsize=(10,4))
df_counts.plot.bar(ax=ax, ylim=(0,5), cmap=plt.cm.Spectral, subplots=True,               
                   legend=None, rot=0)
# Use secondary y-axis(right side)
df_means.plot(ax=ax, secondary_y=True, marker='o', color='r', subplots=True, 
              legend=None, xlim=(0,4))
# Adjust spacing between subplots
plt.subplots_adjust(wspace=0.5, hspace=0.5)
plt.show()

【讨论】:

  • 谢谢。我目前无法深入了解您的答案,但乍一看还不错。
  • 嗨,我只是想更深入地研究一下代码。我很好奇这一步`“将x轴标签准备为字符串”`。是否总是建议将标签转换为字符串(即使在这种情况下,我使用数字作为 x 的值)?
  • 对于我绘图时的这种特殊情况,xticks 原来是默认的整数索引轴(0,1,2...),即使索引有最初是 (10,20,...)。似乎无论出于何种原因,它都在获取默认索引值。因此,作为一种解决方法,索引轴的 dtype 被转换为 str ,然后它就可以工作了。
  • 感谢您的解释。
猜你喜欢
  • 2016-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-01
  • 1970-01-01
  • 2012-05-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多