【问题标题】:plot histogram from pandas dataframe using the list values in (column, row) pairs使用(列,行)对中的列表值从熊猫数据框中绘制直方图
【发布时间】:2018-03-11 21:39:28
【问题描述】:

我想从pandas Dataframe 用以下列绘制直方图(染色体之间重叠和非重叠)。

my_cols = ['chrom', 'len_PIs']
chrom = pd.Series(['chr1', 'chr2', 'chr3'])
len_of_PIs = pd.Series([[np.random.randint(15, 59, 86)],
                    [np.random.randint(18, 55, 92)],
                    [np.random.randint(25, 61, 98)]])

my_df = pd.DataFrame({'chrom': chrom,
                'len_PIs': len_of_PIs},
                 columns=my_cols)

print('\nhere is df5')
print(df5)
print(type(df5))
print(type(df5['len_PIs']))

here is df5
  chrom                                            len_PIs
0  chr1  [[18, 45, 33, 58, 48, 47, 45, 39, 42, 46, 48, ...
1  chr2  [[45, 32, 49, 46, 53, 40, 46, 35, 44, 24, 51, ...
2  chr3  [[53, 32, 35, 35, 49, 31, 57, 42, 46, 49, 49, ...
<class 'pandas.core.frame.DataFrame'>
<class 'pandas.core.series.Series'>

所以,现在我想为每个chrom 使用len_PIs 值制作直方图。

import matplotlib.pyplot as plt

with open('histogram_byChr.png', 'w'):
    fig = plt.figure()
    plt.subplot()
    plt.xlabel('chrom')
    plt.ylabel('len_PIs')
    fig.suptitle('length of PIs distribution for each chromosome')

    # these two method (below) are close but don't work

    plt.plot(my_df.groupby('chrom')['len_PIs'])
    # error message which doesn't make sense to me
    ValueError: could not convert string to float: 'chr3'

    my_df.groupby('chrom').plot.hist(alpha=0.5)
    # Error message
    TypeError: Empty 'DataFrame': no numeric data to plot

【问题讨论】:

  • 您的示例代码仅生成 NaN。可以再看一遍吗?
  • 我刚刚更新了代码。我打错了len_PIs,但这不是我原始代码中的问题。我尝试查看其他拼写错误,但没有发现任何问题。如果看到其他问题,请告诉我。谢谢。

标签: python python-3.x pandas matplotlib histogram


【解决方案1】:

数据似乎相当不寻常地存储在数据框中。然而,您可能只是对其进行迭代并绘制相应的直方图。

## Plot all three histograms in a single plot
fig, ax = plt.subplots()
for i, data in my_df.iterrows():
    ax.hist(data["len_PIs"], label=data['chrom'], alpha=.5)
ax.legend()
plt.show()

## Plot each histogram in its own subplot
fig, axes = plt.subplots(nrows=len(my_df), sharex=True)
for i, data in my_df.iterrows():
    axes[i].hist(data["len_PIs"], label=data['chrom'], alpha=.5)
    axes[i].legend()
plt.show()

【讨论】:

  • 不寻常的原因是len_PIs 的长度与chrom 不同。我本可以将chr1 ... 作为列,但认为不等长度会使直方图绘制复杂化。非常感谢!
  • @everestial007 它没有,例如,如果你这样做,就像我使用堆栈所做的那样。
【解决方案2】:

您需要在此处进行一些数据整形。将您的列表列分解为单独的列 -

df = pd.DataFrame(
        pd.DataFrame(df.len_PIs.tolist())[0].tolist(), index=df.chrom
)

df    
       0   1   2   3   4   5   6   7   8   9   ...     88    89    90    91  \
chrom                                          ...                            
chr1   58  15  55  53  40  25  49  38  47  34  ...    NaN   NaN   NaN   NaN   
chr2   37  42  24  38  24  46  24  20  46  46  ...   43.0  54.0  44.0  22.0   
chr3   35  37  58  57  58  51  60  50  49  43  ...   37.0  32.0  41.0  54.0   

         92    93    94    95    96    97  
chrom                                      
chr1    NaN   NaN   NaN   NaN   NaN   NaN  
chr2    NaN   NaN   NaN   NaN   NaN   NaN  
chr3   25.0  48.0  40.0  35.0  28.0  28.0  

接下来,stack 你的数据水平。最后,拨打groupby + plot

df.stack().groupby(level=0).plot.hist(alpha=0.5, legend=True);
plt.show()

【讨论】:

    猜你喜欢
    • 2020-03-02
    • 2021-10-16
    • 1970-01-01
    • 2019-07-21
    • 2020-10-10
    • 2016-12-08
    • 2019-09-12
    • 2017-06-09
    • 2018-07-05
    相关资源
    最近更新 更多