首页 > 解决方案 > 我的颜色图的标签只显示了一个

问题描述

为什么我的图只显示 1 个图例,希望图例显示两个 DataFrame 的标签。我发现了一个类似的问题,但我无法将其应用于我的数据:Legend only shows one label when plotting with pandas 数据:https ://github.com/DwightZC/Learning

data=pd.read_csv('Data gathered1.csv')
data
data['CONTAMINANTS'] = data['CONTAMINANTS'].str.split(pat=', ')
data_long = data.explode('CONTAMINANTS')
data_long['CONTAMINANTS'].value_counts()

  ACT = {'0': 'No Activity', 
     '1A' : 'CONTAMINATION CONFIRMED',
     '1B' : 'CONTAMINATION CONFIRMED', 
     '2A' :'INVESTIGATION',
     '2B': 'INVESTIGATION',
     '3':'CORRECTIVE ACTION PLANNING',
     '4': 'IMPLEMENT ACTION',
    '5': 'MONITOR ACTION',
     '6':'INACTIVE'
      }


  data['STATUS'] = data['ACT-STATUS'].apply(lambda x: ACT[x])
  data

  color = { 'No Activity': 'black', 
      'CONTAMINATION CONFIRMED':'lightblue',
     'INVESTIGATION':'red',
     'CORRECTIVE ACTION PLANNING':'pink',
     'IMPLEMENT ACTION':'yellow',
     'MONITOR ACTION':'green',
     'INACTIVE':'gray'
      }


data['COLOR'] = data['STATUS'].apply(lambda x: color[x])
data
x=data['LONGITUDE']
y= data["LATITUDE"]

import cartopy.io.shapereader as shpreader

reader = shpreader.Reader('cb_2018_us_county_5m')

counties = list(reader.geometries())

COUNTIES = cfeature.ShapelyFeature(counties, ccrs.PlateCarree())
reader2 = shpreader.Reader('City')

city = list(reader2.geometries())

Cities = cfeature.ShapelyFeature(city, ccrs.PlateCarree())




 import matplotlib.pyplot as plt 
 import numpy as np
  import cartopy.crs as ccrs
 import cartopy.io.img_tiles as cimgt
 import io
 from urllib.request import urlopen, Request
 from PIL import Image

def image_spoof(self, tile): # this function pretends not to be a Python script
url = self._image_url(tile) # get the url of the street map API
req = Request(url) # start request
req.add_header('User-agent','Anaconda 3') # add user agent to request
fh = urlopen(req) 
im_data = io.BytesIO(fh.read()) # get image
fh.close() # close url
img = Image.open(im_data) # open image with PIL
img = img.convert(self.desired_tile_form) # set image format
return img, self.tileextent(tile), 'lower' # reformat for cartopy

cimgt.OSM.get_image = image_spoof # reformat web request for street map spoofing
osm_img = cimgt.OSM() # spoofed, downloaded street map

fig = plt.figure(figsize=(12,9)) # open matplotlib figure
ax1 = plt.axes(projection=osm_img.crs) # project using coordinate reference 
system (CRS) of street 
mapcenter_pt = [26.2271, -98.2087] # lat/lon hidalgo
zoom = 0.5 # for zooming out of center point
extent = [center_pt[1]-(zoom*2.0),center_pt[1]+(zoom*2.0),center_pt[0]- 
zoom,center_pt[0]+zoom] # 
adjust to zoom
ax1.set_extent(extent) # set extents
ax1.scatter(x,y,c=data['COLOR'], transform=ccrs.PlateCarree())
scale = np.ceil(-np.sqrt(2)*np.log(np.divide(zoom,350.0))) # empirical solve 
for scale based on zoom
scale = (scale<20) and scale or 19 # scale cannot be larger than 19
ax1.add_image(osm_img, int(scale)) # add OSM with zoom specification
ax1.set_title("Hidalgo County")
#ax1.add_feature(COUNTIES, facecolor='none', edgecolor='gray')
#ax1.add_feature(Cities, facecolor='none', edgecolor='gray')
plt.show()

在此处输入图像描述

标签: dataframematplotlibopenstreetmapscatter-plotcartopy

解决方案


在此处输入图像描述

我把你的数据文件下载到我的电脑上,然后我写了以下内容

import numpy as np
import matplotlib.pyplot as plt
from csv import reader

# the following two dicts are copied from your question
ACT = {'0': 'No Activity', '1A' : 'CONTAMINATION CONFIRMED',
       '1B' : 'CONTAMINATION CONFIRMED', '2A' :'INVESTIGATION',
       '2B': 'INVESTIGATION', '3':'CORRECTIVE ACTION PLANNING',
       '4': 'IMPLEMENT ACTION', '5': 'MONITOR ACTION', '6':'INACTIVE'}
color = {'No Activity': 'black', 'CONTAMINATION CONFIRMED':'lightblue',
         'INVESTIGATION':'red', 'CORRECTIVE ACTION PLANNING':'pink',
         'IMPLEMENT ACTION':'yellow', 'MONITOR ACTION':'green', 'INACTIVE':'gray'}
# but we don't need ACT, we need its inverse…
ACT2codes = {}
for k, v in ACT.items(): ACT2codes.setdefault(v, []). append(k)

# ######################## let's read the data ########################
# lines is a generator, returns lines split on commas (respecting quoting)
# data is a dictionary of tuples of strings, indexed by the headers
lines = reader(open('hidalgo.csv', 'r'))    
data = {k:v for k, v in zip(next(lines), zip(*lines))}    
# but something it's better understood as an array of floats
for k in ('LONGITUDE',  'LATITUDE'):
    data[k] = np.array([float(item) for item in data[k]])        
# and something else is better understood as an array of strings,
# because we'll use np.where to find the indices required for plotting
data['ACT-STATUS'] = np.array(data['ACT-STATUS'])    
# ######################## ready to plot ########################
plt.figure(constrained_layout=1)
# for each action, plot some points with same color and same label
for action in ACT2codes.keys():
    # what are the indices of this batch of points?
    idx = []
    for code in ACT2codes[action]:
        idx += list(*np.where(data['ACT-STATUS']==code))
    plt.scatter(data['LONGITUDE'][idx],
                data['LATITUDE'][idx],
                color=color[action], label=action)
plt.legend() ; plt.show()

很抱歉,我不太了解pandas,所以我没有使用它……另一方面,使用该csv模块获取数据似乎并不过分复杂——而且,我省略了所有制图的东西,以保持数据处理阶段的证据。


推荐阅读