Я пытался создать картограмму, изменив карту SVG с изображением всех округов США. Основной подход отражен в Передача данных. Поскольку SVG — это, по сути, просто XML, этот подход использует парсер BeautifulSoup.
Дело в том, что парсер не захватывает все элементы path
в файле SVG. Следующее зафиксировало только 149 путей (из более чем 3000):
#Open SVG file
svg=open(shp_dir+'USA_Counties_with_FIPS_and_names.svg','r').read()
#Parse SVG
soup = BeautifulSoup(svg, selfClosingTags=['defs','sodipodi:namedview'])
#Identify counties
paths = soup.findAll('path')
len(paths)
Однако я знаю, что их гораздо больше, как по физическому осмотру, так и по тому факту, что Методы ElementTree фиксируют 3143 пути с помощью следующей процедуры:
#Parse SVG
tree = ET.parse(shp_dir+'USA_Counties_with_FIPS_and_names.svg')
#Capture element
root = tree.getroot()
#Compile list of IDs from file
ids=[]
for child in root:
if 'path' in child.tag:
ids.append(child.attrib['id'])
len(ids)
Я еще не понял, как писать из объекта ElementTree
таким образом, чтобы не все испортилось.
#Define style template string
style='font-size:12px;fill-rule:nonzero;stroke:#FFFFFF;stroke-opacity:1;'+\
'stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;'+\
'stroke-linecap:butt;marker-start:none;stroke-linejoin:bevel;fill:'
#For each path...
for child in root:
#...if it is a path....
if 'path' in child.tag:
try:
#...update the style to the new string with a county-specific color...
child.attrib['style']=style+col_map[child.attrib['id']]
except:
#...if it's not a county we have in the ACS, leave it alone
child.attrib['style']=style+'#d0d0d0'+'\n'
#Write modified SVG to disk
tree.write(shp_dir+'mhv_by_cty.svg')
Приведенная выше процедура модификации/записи дает это чудовище:
Мой главный вопрос таков: почему BeautifulSoup не удалось захватить все теги path
? Во-вторых, почему изображение, измененное с помощью ElementTree
объектов, должно иметь все эти внеклассные занятия? Мы будем очень признательны за любые советы.
svg_soup = BeautifulSoup(svg); paths = svg_soup.find_all('path'); len(paths)
, который выдал 3143. Возможно, вам нужно обновитьbs4
? - person MattDMo   schedule 19.01.2015