2

米国のすべての郡を表すSVG マップを変更して、コロプレス マップを生成しようとしていました。基本的なアプローチはFlowing Dataによってキャプチャされます。SVG は基本的に単なる XML であるため、このアプローチではBeautifulSoupパーサーを利用します。

path問題は、パーサーがSVG ファイル内のすべての要素をキャプチャするわけではないということです。次の例では、(3000 以上のパスのうち) 149 のパスのみがキャプチャされました。

#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メソッドが次のルーチンで 3,143 のパスをキャプチャするという事実から、さらに多くのパスが存在することがわかっています。

#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')

上記の変更/書き込みルーチンは、この怪物をもたらします。

郡ごとの醜い住宅価格の中央値

path私の主な質問はこれです: BeautifulSoup がすべてのタグをキャプチャできなかったのはなぜですか? 第二に、オブジェクトで修正された画像ElementTreeに課外活動がすべて含まれているのはなぜでしょうか? アドバイスをいただければ幸いです。

4

2 に答える 2

2

alexce の答えは、最初の質問に対して正しいです。2番目の質問に関する限り:

ElementTree オブジェクトで変更された画像に、課外活動がすべて含まれているのはなぜでしょうか? "

答えは簡単です。すべて<path>の要素が郡を描くわけではありません。具体的には、削除する必要がある要素が 2 つありid="State_Lines"ます。id="separator"色のデータセットを提供しなかったため、郡ごとにランダムな 16 進カラー ジェネレーター (ここから適応) を使用し、の XMLlxmlを解析して各要素を反復処理し、上記のものをスキップしました。.svg<path>

from lxml import etree as ET
import random

def random_color():
    r = lambda: random.randint(0,255)
    return '#%02X%02X%02X' % (r(),r(),r())

new_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:'

tree = ET.parse('USA_Counties_with_FIPS_and_names.svg')
root = tree.getroot()
for child in root:
    if 'path' in child.tag and child.attrib['id'] not in ["separator", "State_Lines"]:
        child.attrib['style'] = new_style + random_color()

tree.write('counties_new.svg')

この素敵な画像になります:

于 2015-01-19T03:07:30.793 に答える