基于Basemap的带数据气泡世界地图代码优化问询
Fixing Your Basemap Bubble Chart Issues
Let’s tackle your core problems—misplaced bubbles, missing country context, and unconfigured bubble labels/sizing—with a hands-on, working solution that aligns with your target output.
Key Problems in Your Original Code
- You were using
ResandSeacolumns as coordinates instead of actual latitude/longitude values (that’s why bubbles were in the wrong spot!) - No logic to scale bubbles by conversion rate or add descriptive labels
- Missing country borders to ground the map and make locations clear
Modified Full Code
First, install any missing dependencies if needed:
pip install pycountry pandas matplotlib basemap
Here’s the revised code with all your requirements met:
import pandas as pd from mpl_toolkits.basemap import Basemap import matplotlib.pyplot as plt import pycountry # Load your dataset (replace with your actual data loading logic) conversion_comparison = pd.DataFrame([ {"Country": "Spain", "Sea": 6179, "Res": 85, "ConvRate(%)": 1.38, "Country_codes": "ES"}, {"Country": "United Kingdom", "Sea": 495, "Res": 99, "ConvRate(%)": 2.00, "Country_codes": "GB"}, {"Country": "France", "Sea": 473, "Res": 12, "ConvRate(%)": 2.55, "Country_codes": "FR"}, {"Country": "United States", "Sea": 442, "Res": 7.8, "ConvRate(%)": 1.76, "Country_codes": "US"}, {"Country": "Italy", "Sea": 358, "Res": 7.4, "ConvRate(%)": 2.07, "Country_codes": "IT"}, {"Country": "Germany", "Sea": 153, "Res": 3.3, "ConvRate(%)": 2.15, "Country_codes": "DE"}, {"Country": "Argentina", "Sea": 135, "Res": 1.9, "ConvRate(%)": 1.41, "Country_codes": "AR"}, {"Country": "Ireland", "Sea": 132, "Res": 3.3, "ConvRate(%)": 2.49, "Country_codes": "IE"}, {"Country": "Belgium", "Sea": 122, "Res": 4.3, "ConvRate(%)": 3.51, "Country_codes": "BE"}, {"Country": "Israel", "Sea": 109, "Res": 2.2, "ConvRate(%)": 1.82, "Country_codes": "IL"}, ]) # Function to fetch country center coordinates using pycountry + Basemap geocoding def get_country_coords(country_name): try: country = pycountry.countries.lookup(country_name) return m.geocode(country.name, returnxy=True) except: return None, None # Set up high-resolution figure my_dpi = 100 plt.figure(figsize=(26, 18), dpi=my_dpi) # Initialize Basemap with full world coverage and clean projection m = Basemap(projection='mill', llcrnrlon=-180, llcrnrlat=-65, urcrnrlon=180, urcrnrlat=80) m.drawmapboundary(fill_color='#A6CAE0', linewidth=0) m.fillcontinents(color='grey', alpha=0.3) m.drawcoastlines(linewidth=0.2, color="white") m.drawcountries(linewidth=0.3, color="white") # Add country borders for clarity # Add latitude/longitude columns to your dataset conversion_comparison['lon'], conversion_comparison['lat'] = zip(*conversion_comparison['Country'].apply(get_country_coords)) conversion_comparison = conversion_comparison.dropna(subset=['lon', 'lat']) # Drop any invalid entries # Convert geographic coordinates to map projection coordinates x, y = m(conversion_comparison['lon'].values, conversion_comparison['lat'].values) # Plot bubbles sized by conversion rate (scale factor adjusted for visibility) bubble_size = conversion_comparison['ConvRate(%)'] * 600 scatter = m.scatter(x, y, s=bubble_size, alpha=0.7, c='#ff7f0e', edgecolor='white', linewidth=1) # Add labels with country code + conversion rate for idx, row in conversion_comparison.iterrows(): plt.text(row['lon'] + 2, row['lat'], f"{row['Country_codes']}\n{row['ConvRate(%)']}%", fontsize=10, ha='left', va='center', bbox=dict(facecolor='white', alpha=0.8, pad=2)) # Final layout adjustments plt.title('Country Conversion Rates', fontsize=16, pad=20) plt.tight_layout() plt.show()
What Changed & Why
- Coordinate Fix: We added a function to fetch each country’s latitude/longitude, ensuring bubbles land exactly on their respective countries. If you don’t want to use
pycountry, you can manually add lat/lon columns to your dataset for precise control. - Bubble Sizing: The
sparameter now usesConvRate(%)multiplied by a scale factor (600) to make higher conversion rates appear as larger bubbles. - Clear Labels: We loop through each data point to add a readable label with the country code and conversion rate, using a semi-transparent background to avoid clashing with the map.
- Map Improvements:
- Switched to the
millprojection for better world coverage - Added
drawcountries()to show distinct country borders - Adjusted DPI for sharper, higher-resolution output
- Switched to the
Alternative: Hardcode Coordinates
If you prefer to avoid external libraries, manually add these lat/lon columns to your dataframe:
conversion_comparison['lat'] = [40.4637, 55.3781, 46.2276, 37.0902, 41.8719, 51.1657, -38.4161, 53.4129, 50.5039, 31.0461] conversion_comparison['lon'] = [-3.7492, -3.4360, 2.2137, -95.7129, 12.5674, 10.4515, -63.6167, -8.2439, 4.4699, 34.8516]
内容的提问来源于stack exchange,提问作者punit kumar Sharma
相关产品推荐
相关产品推荐

