【问题标题】:Best way to graph a dictionary with multiple values per key? [closed]用每个键绘制多个值的字典的最佳方法? [关闭]
【发布时间】:2022-01-09 20:56:12
【问题描述】:

我需要创建一个包含 DNA 序列 ID 和分子量字典的散点图。许多 DNA 序列是不明确的,因此它们可以有许多可能的分子量(因此每个键有许多值)。字典看起来像这样,但许多键实际上有更多的值(为简洁起见,我删除了一些)。

{'seq_7009': [6236.9764, 6279.027699999999,
   6319.051799999999, 6367.049999999999],
 'seq_418': [3716.3642000000004, 3796.4124000000006],
 'seq_9143_unamb': [4631.958999999999],
 'seq_2888': [5219.3359, 5365.4089],
 'seq_1101': [4287.7417, 4422.8254]}

我有另一个名为get_all_weights 的函数可以生成这个字典,所以我尝试调用该函数然后绘制结果图。这是我到目前为止所拥有的,基于此站点上的另一篇文章,但它不起作用:

import matplotlib.pyplot as plt
import itertools

def graph_weights(file_name):
    with open (file_name) as file:
        d = {} # Initialize a dictionary and then fill it with the results of the get_all_weights function
        d.update(get_all_weights(file_name))  
        for k, v in d.items():
            x = [key for (key,values) in b.items() for _ in range(len(values))]
            y = [val for subl in d.values() for val in subl]
            ax.plot(x, y)
    plt.show()

有谁知道我如何做到这一点?该图应在 x 轴上显示序列 ID,在 y 轴上显示值,并且应该清楚地表明同一值可以多次出现。

【问题讨论】:

  • 你知道你可以做d = get_all_weights(...),对吧?
  • 不要使用with,因为你从不使用file。如果您确实使用了with,请将所有后期处理都放在外面。尽快关闭文件。
  • 展示你得到的和你想要的。这是图像合适的一种情况
  • 我们不需要看生成代码。正确的minimal reproducible example 只需要d = <first snippet>

标签: python dictionary matplotlib plot


【解决方案1】:

并且应该明确相同的值可以出现多次

使用默认的 matplotlib 绘图,这将不清楚,因为相似/相同的点会直接重叠。

虽然manually add jittering 是可能的,但最简单的方法是使用seaborn 的swarmplotstripplot

  1. 创建一个数据框from_dict:

    import pandas as pd
    data = pd.DataFrame.from_dict(d, orient='index').T
    
    #     seq_7009    seq_418  seq_9143_unamb   seq_2888   seq_1101
    # 0  6236.9764  3716.3642        4631.959  5219.3359  4287.7417
    # 1  6279.0277  3796.4124             NaN  5365.4089  4422.8254
    # 2  6319.0518        NaN             NaN        NaN        NaN
    # 3  6367.0500        NaN             NaN        NaN        NaN
    
  2. 然后使用swarmplotstripplot

    import seaborn as sns
    sns.swarmplot(data=data)
    

    import seaborn as sns
    sns.stripplot(data=data)
    

【讨论】:

    【解决方案2】:

    您使用以下代码绘制每个序列 ID 及其各自的值。

    import matplotlib.pyplot as plt
    
    d = {'seq_7009': [6236.9764, 6279.027699999999,
       6319.051799999999, 6367.049999999999],
     'seq_418': [3716.3642000000004, 3796.4124000000006],
     'seq_9143_unamb': [4631.958999999999],
     'seq_2888': [5219.3359, 5365.4089],
     'seq_1101': [4287.7417, 4422.8254]}
    
    plt.figure(figsize=(15,5))
    xlabels = []
    for i, key in enumerate(d):
        if len(d[key])!=0:
            plt.scatter([i+1]*len(d[key]), d[key], c="#396B8B")
        xlabels.append(key)   
    plt.xticks(list(range(1, len(xlabels)+1)), xlabels, rotation='horizontal')
    plt.grid(axis="y")
    plt.title("Molecular Weight by Sequence ID")
    plt.ylabel("Molecular Weight")
    plt.show()
    

    【讨论】:

    • 您不需要将 1 添加到范围和枚举中,因为它们永远不会直接显示给用户
    • 另外,xlabels = list(d.keys())
    • 非常感谢您的帮助。正如您可能知道的那样,我对 Python 还是很陌生。我尝试了这段代码,它在你编写时运行良好,但是当我编辑它以将字典定义为 (get_all_weights(file_name)) 时,它会抛出错误“x 和 y 必须是相同的大小”。不知道为什么
    猜你喜欢
    • 2022-11-26
    • 2014-05-21
    • 2010-09-07
    • 2021-02-01
    • 2011-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    相关资源
    最近更新 更多