使用matplotlib和pandas制作条形图

问题描述 投票:0回答:1

enter image description here

我有一堆数据,正在尝试将它们绘制为每种岩性的条形图。我希望 Y 轴是每种岩性的每个 RQD Bin 的百分比,而不是总长度。我知道当前的“groupby”将不起作用,因为它当前正在对长度求和,但我不熟悉要更新什么来解决此问题。任何帮助将不胜感激!

这是我当前的代码...

    # Define ranges and corresponding names
    ranges = [(0, 10), 
        (10.00001, 20), 
          (20.00001, 30), 
          (30.00001, 40), 
          (40.00001, 50), 
          (50.00001, 60), 
          (60.00001, 70), 
          (70.00001, 80), 
          (80.0001,90), 
          (90.00001, 1000)]
    names = ["0 to 10", 
         "10 to 20", 
         "20 to 30", 
         "30 to 40", 
         "40 to 50", 
         "50 to 60", 
         "60 to 70", 
         "70 to 80", 
         "80 to 90", 
         "90 to 100"]

    # Function to assign names based on ranges
    def assign_name(value):
      for low, high in ranges:
        if low <= value <= high:
          return names[ranges.index((low, high))]
      return None  # Handle values outside all ranges

    # Add a new column based on RQD ranges
    df['RQD_Bin'] = df['RQD'].apply(assign_name)
    df["Length"] = df["To"] - df["From"]

    # Group data by lithology and calculate counts for each RQD_Bin
    lithology_distr = df.groupby(['Lithology', 'RQD_Bin'])['Length'].sum().unstack()

    # Create a bar chart
    lithology_distr.plot(kind='bar', stacked=False)  # Set stacked=False for separate bars

    # Customize the plot for better readability
    plt.xlabel('RQD (%)')
    plt.ylabel('Total Length Contribution')  # Update y-axis label
    plt.title('RQD by Lithology')
    plt.legend(title='RQD Bin')
    plt.xticks(rotation=90)  # Rotate x-axis labels to prevent overlapping

    # Display the chart and plot
    plt.savefig("RQD_Distribution.png")  # Replace with ".jpg" or other format if needed
    plt.show()

python pandas charts
1个回答
0
投票

您没有提供数据框,所以我创建了一个。你快三了:

import matplotlib.pyplot as plt
import pandas as pd

data = {
    'Lithology': ['Sandstone', 'Shale', 'Sandstone', 'Shale'],
    'RQD': [25, 55, 85, 15],
    'From': [0, 0, 100, 100],
    'To': [100, 100, 200, 200]
}
df = pd.DataFrame(data)

import matplotlib.pyplot as plt
import pandas as pd

ranges = [(0, 10), 
          (10.00001, 20), 
          (20.00001, 30), 
          (30.00001, 40), 
          (40.00001, 50), 
          (50.00001, 60), 
          (60.00001, 70), 
          (70.00001, 80), 
          (80.0001, 90), 
          (90.00001, 1000)]
names = ["0 to 10", 
         "10 to 20", 
         "20 to 30", 
         "30 to 40", 
         "40 to 50", 
         "50 to 60", 
         "60 to 70", 
         "70 to 80", 
         "80 to 90", 
         "90 to 100"]

def assign_name(value):
    for low, high in ranges:
        if low <= value <= high:
            return names[ranges.index((low, high))]
    return None  

df['RQD_Bin'] = df['RQD'].apply(assign_name)
df["Length"] = df["To"] - df["From"]

grouped = df.groupby(['Lithology', 'RQD_Bin'])['Length'].sum()
total_length = df.groupby('Lithology')['Length'].sum()
percentage = 100 * grouped / total_length.reindex(grouped.index, level=0)
lithology_distr = percentage.unstack()


ax = lithology_distr.plot(kind='bar', stacked=False, figsize=(10, 7))
ax.set_xlabel('Lithology')
ax.set_ylabel('Percentage of Total Length (%)')
ax.set_title('Percentage RQD Distribution by Lithology')
ax.legend(title='RQD Bin')
plt.xticks(rotation=45)  


plt.show()

这给出了

© www.soinside.com 2019 - 2024. All rights reserved.