如何用Matplotlib绘制含年份、GDP、自杀数的Pandas数据集?
Let's break down what's going wrong here and fix your visualizations step by step:
First, the core issue: your suicides_gdp is a MultiIndex Series—its index has two levels (year and gdp_for_year ($)), with suicides_no as the values. Your original code fails because matplotlib can't handle MultiIndex data directly for axes, and you mixed up parameters for barh.
Step 1: Clean and Restructure the Data
First, convert the MultiIndex Series to a flat DataFrame, and clean the GDP values (they're strings with commas, so we need to turn them into numeric values):
import pandas as pd import matplotlib.pyplot as plt # Convert the Series to a DataFrame and reset the index suicides_gdp_df = suicides_gdp.reset_index() # Clean GDP column: remove commas and convert to float suicides_gdp_df[' gdp_for_year ($) '] = suicides_gdp_df[' gdp_for_year ($) '].str.replace(',', '').astype(float)
Step 2: Line Plot (Dual Y-Axis for Different Scales)
Since GDP and suicide counts are on wildly different scales, we need a dual y-axis to visualize both clearly:
fig, ax1 = plt.subplots(figsize=(12, 6)) # Left Y-axis: Suicide Counts color = 'tab:red' ax1.set_xlabel('Year') ax1.set_ylabel('Number of Suicides', color=color) ax1.plot(suicides_gdp_df['year'], suicides_gdp_df['suicides_no'], color=color, marker='o', linewidth=2, label='Suicides') ax1.tick_params(axis='y', labelcolor=color) # Right Y-axis: GDP ax2 = ax1.twinx() color = 'tab:blue' ax2.set_ylabel('GDP (USD)', color=color) ax2.plot(suicides_gdp_df['year'], suicides_gdp_df[' gdp_for_year ($) '], color=color, marker='s', linewidth=2, label='GDP') ax2.tick_params(axis='y', labelcolor=color) # Add legend and title fig.tight_layout() fig.legend(loc='upper right', bbox_to_anchor=(1.15, 1)) plt.title('Russia: Suicide Counts vs GDP (1989-2015)') plt.show()
Why your original line plot failed: You tried passing the entire MultiIndex (suicides_gdp.index) as the x-axis. Matplotlib can't interpret a 2-level index as a sequential x-value—we need to extract just the year column as our x-axis.
Step 3: Bar Plot (Vertical or Horizontal)
Vertical Bar Plot (Suicides as Bars, GDP as Line)
This is a common way to show categorical data (years) with two metrics:
fig, ax1 = plt.subplots(figsize=(14, 7)) # Vertical bars for suicide counts color = 'tab:red' bars = ax1.bar(suicides_gdp_df['year'], suicides_gdp_df['suicides_no'], color=color, alpha=0.7, label='Suicides') ax1.set_xlabel('Year') ax1.set_ylabel('Number of Suicides', color=color) ax1.tick_params(axis='y', labelcolor=color) # Rotate year labels to avoid overlap plt.xticks(rotation=45) # Add value labels to bars for bar in bars: height = bar.get_height() ax1.text(bar.get_x() + bar.get_width()/2., height + 1000, f'{int(height)}', ha='center', va='bottom') # Right Y-axis for GDP line ax2 = ax1.twinx() color = 'tab:blue' ax2.plot(suicides_gdp_df['year'], suicides_gdp_df[' gdp_for_year ($) '], color=color, marker='o', linewidth=2, label='GDP') ax2.set_ylabel('GDP (USD)', color=color) ax2.tick_params(axis='y', labelcolor=color) # Add legend and title fig.tight_layout() fig.legend(loc='upper right', bbox_to_anchor=(1.18, 1)) plt.title('Russia: Suicide Counts and GDP by Year') plt.show()
Horizontal Bar Plot
Your original barh code had parameter mix-ups—barh uses y for the categorical axis (years) and width for the numerical value (suicides). Here's the corrected version:
fig, ax1 = plt.subplots(figsize=(10, 12)) # Horizontal bars for suicide counts color = 'tab:red' bars = ax1.barh(suicides_gdp_df['year'], suicides_gdp_df['suicides_no'], color=color, alpha=0.7, label='Suicides') ax1.set_ylabel('Year') ax1.set_xlabel('Number of Suicides', color=color) ax1.tick_params(axis='x', labelcolor=color) # Add value labels to bars for bar in bars: width = bar.get_width() ax1.text(width + 500, bar.get_y() + bar.get_height()/2, f'{int(width)}', ha='left', va='center') # Top X-axis for GDP line (since it's a horizontal plot, use twiny()) ax2 = ax1.twiny() color = 'tab:blue' ax2.plot(suicides_gdp_df[' gdp_for_year ($) '], suicides_gdp_df['year'], color=color, marker='s', linewidth=2, label='GDP') ax2.set_xlabel('GDP (USD)', color=color) ax2.tick_params(axis='x', labelcolor=color) # Add legend and title fig.tight_layout() fig.legend(loc='upper right', bbox_to_anchor=(1.2, 1)) plt.title('Russia: Suicide Counts and GDP by Year (Horizontal)') plt.show()
Why your original barh failed: You passed x="suicides_no" and y=["year", " gdp_for_year ($) "]—this is backwards (barh uses y for categories) and you tried to pass two columns as the y-axis, which matplotlib can't handle. We only need year as the y-axis for horizontal bars.
内容的提问来源于stack exchange,提问作者A A

