मुझे matplotlib में कुछ असामान्य बार प्लॉट बनाने की आवश्यकता है और मानक कार्यक्षमता मुझे जो चाहिए वह प्रदान नहीं करती है।

मैंने कुछ दस्तावेज़ों को क्लस्टर किया है और प्रति क्लस्टर 5 सबसे महत्वपूर्ण कीवर्ड दिखाना चाहता हूं। पहली समस्या यह है कि मेरे पास प्रति समूह एक समूह है जिसमें 5 अलग-अलग बार होते हैं। दूसरी समस्या यह है कि इन अलग-अलग सलाखों के लेबल महत्वपूर्ण हैं, समूहों में समान नहीं हैं और अद्वितीय भी नहीं हैं।

मेरे पास एक अस्थायी प्रोटोटाइप है जो इस तरह दिखता है:

Link

मैंने सभी अलग-अलग सलाखों को सही क्रम में प्लॉट किया और उन्हें खाली प्रविष्टियों से अलग कर दिया। सबसे बड़ी समस्या (बदसूरत होने के अलावा) यह है कि समूह की पहचान करने का एकमात्र तरीका समूहों की गिनती करना है। यह बहुत मदद करेगा यदि समूहों को या तो रंग या किसी अन्य चीज़ से पहचाना जा सकता है, लेकिन मैं यह नहीं समझ सकता कि यह कैसे करना है।

संपादित करें: यहां कुछ अनुरोधित खिलौना डेटा के साथ-साथ मेरे पास पहले से मौजूद प्लॉट का उत्पादन करने के लिए उपयोग किया जाने वाला कोड भी है।

खिलौना डेटा:

निम्नलिखित दो पांडा डेटाफ़्रेम एक सरणी में शामिल हैं। दो कोड ब्लॉक में df_list[i].to_csv() के परिणाम शामिल हैं। मुझे उम्मीद है कि यह मदद करता है, लेकिन इस समस्या के संदर्भ में वास्तविक डेटा वास्तव में मायने नहीं रखता है, इसलिए आप केवल अपना डेटाफ्रेम भी बना सकते हैं।

,features,score
0,knowledg,0.09862235117497174
1,manag,0.07812351138840486
2,innov,0.06502084705448799
3,organ,0.0561819290497529
4,km,0.05580332888282127

तथा

,features,score
0,knowledg,0.04217018718591911
1,develop,0.03423580137595049
2,manag,0.032239226503136
3,system,0.031064303713788467
4,sustain,0.029628875636649198

कोड:

वर्तमान समाधान के लिए दृष्टिकोण सभी व्यक्तिगत डेटाफ़्रेम को एक डेटाफ़्रेम में संयोजित करना है, जहाँ आवश्यक हो वहाँ खाली प्रविष्टियाँ जोड़ना और परिणाम प्लॉट करना है।

def plot_all_clusters_words(dfs):
    # target structure: word as non unique column, value as other non unique column
    df_dict_list = []
    for df in dfs:
        for index, row in df.iterrows():
            df_dict_list.append({"word": row.features, "value": row.score})
        df_dict_list.append({"word": "", "value": 0})
    df_dict_list = df_dict_list[:-1]
    new_df = pd.DataFrame(df_dict_list)
    new_df.plot.bar(x="word")   
    plt.show()
    return new_df

ध्यान दें:

मुझे समूहों को आसानी से पहचानने का एक तरीका चाहिए, यदि आप ऊपर बताए गए तरीकों से अलग दृष्टिकोण जानते हैं, तो बेझिझक ऐसा करें।

0
Lars Wigger 21 पद 2020, 13:43
यदि आपको मेल द्वारा संपादन के बारे में सूचित नहीं किया जाता है, तो मैं इस टिप्पणी का उपयोग करता हूं।
 – 
Lars Wigger
21 पद 2020, 15:32

1 उत्तर

सबसे बढ़िया उत्तर

प्रत्येक डेटाफ़्रेम के लिए plt.bar को कॉल करना, प्रत्येक का अपना लेबल और रंग है, निम्न प्लॉट बनाएगा:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from io import StringIO

df1_str = '''features,score
0,knowledg,0.09862235117497174
1,manag,0.07812351138840486
2,innov,0.06502084705448799
3,organ,0.0561819290497529
4,km,0.05580332888282127'''
df2_str = '''features,score
0,knowledg,0.04217018718591911
1,develop,0.03423580137595049
2,manag,0.032239226503136
3,system,0.031064303713788467
4,sustain,0.029628875636649198'''
df1 = pd.read_csv(StringIO(df1_str))
df2 = pd.read_csv(StringIO(df2_str))

dfs = [df1, df2]
cluster_names = [f'cluster {i}' for i in range(1, len(dfs) + 1)]
colors = plt.cm.rainbow(np.linspace(0, 1, len(dfs)))
bar_width = 0.8 # width of individual bars
cluster_gap = 0.2 # extra distance between clusters
starts = np.append(0, np.array([len(df) + cluster_gap for df in dfs]).cumsum())
all_tickpos = [s + np.arange(len(df)) for df, s in zip(dfs, starts)]
for df, name, color, tickpos in zip(dfs, cluster_names, colors, all_tickpos):
    plt.bar(tickpos, df['score'], width=bar_width, color=color, label=name)
plt.xticks(np.concatenate(all_tickpos), [f for df in dfs for f in df['features']], rotation=90)
plt.legend()
plt.tight_layout()
plt.show()

resulting plot

1
JohanC 22 पद 2020, 11:53
यह अच्छा लग रहा है, लेकिन एक समस्या है: लेबल गलत हैं। उदाहरण के लिए, क्लस्टर 1 के लिए विकास दो बार प्रकट होता है, भले ही वह इसका हिस्सा न हो। जब मैं अपने डेटा पर थोड़ा प्रयोग करता हूं, तो पैटर्न निम्न होता है: यह केवल अंतिम क्लस्टर के लिए लेबल का उपयोग करता है और उन्हें n बार दोहराता है (जहां n क्लस्टर की संख्या है, इस मामले में 2)। वास्तविक मान सही प्रतीत होते हैं, केवल लेबल गलत हैं। इसके अतिरिक्त, यह केवल 8 क्लस्टर तक खींचता है। 9वें क्लस्टर से, यह बिल्कुल भी बार नहीं खींचता है, केवल खाली (और गलत) लेबल हैं।
 – 
Lars Wigger
22 पद 2020, 11:07
कोड की जाँच के लिए धन्यवाद। समूहों की संख्या रंगों की संख्या से सीमित थी ('उच्चारण' कॉलोरमैप में केवल 8 रंग हैं)। मैंने इंद्रधनुष रंगरूप से समान दूरी वाले रंगों की सटीक संख्या का उपयोग करने के लिए कोड बदल दिया। लेबल के लिए, मैंने गलती से डबल फॉर-लूप के लिए गलत ऑर्डर का इस्तेमाल किया। इसे अब ठीक कर दिया गया है।
 – 
JohanC
22 पद 2020, 11:57
धन्यवाद, अब यह अधिक संख्या में क्लस्टर के लिए भी सही ढंग से काम कर रहा है। मैं इस समस्या को अपने आप हल नहीं कर सकता था, लेकिन मुझे शेष लोगों से निपटने में सक्षम होना चाहिए।
 – 
Lars Wigger
22 पद 2020, 19:46