简体   繁体   English

Altair 使用 selenium chromedriver 自动保存图表

[英]Altair automatic save chart using selenium chromedriver

Asking this again as the previous has been closed without any useful solution.再次询问此问题,因为前一个已关闭,没有任何有用的解决方案。

I am trying to produce few charts in a loop and save them automatically.我正在尝试循环生成一些图表并自动保存它们。

I am working on Windows, using Chrome.我在 Windows 上工作,使用 Chrome。

I have been following the documentation on how to save a chart in svg.我一直在关注有关如何在 svg 中保存图表的文档

I downloaded the appropriate ChromeDriver for my Chrome version.我为我的 Chrome 版本下载了合适的 ChromeDriver。 gdf is my geodataframe and everything works smoothly and I can generate and manually save charts. gdf是我geodataframe,一切工作顺利,我可以节省图表手动生成和。

Also, this example taken from the chromium documentation works:此外,这个来自铬文档的例子有效:

import time
from selenium import webdriver

driver = webdriver.Chrome('pathtochromedriver/chromedriver_win32/chromedriver.exe')
driver.get('http://www.google.com/');
time.sleep(5) # Let the user actually see something!
search_box = driver.find_element_by_name('q')
search_box.send_keys('ChromeDriver')
search_box.submit()
time.sleep(5) # Let the user actually see something!
driver.quit()

Below is the piece of code I am trying to run:下面是我试图运行的一段代码:

#Chromedriver for headless run and chart automatic save
from selenium import webdriver
from selenium.webdriver.chrome.options import Options 

chrome_options = Options()  
chrome_options.add_argument("--headless") 
####### None of the following work! 
#driver = webdriver.Chrome(chrome_options=chrome_options, executable_path=r'pathtochromedriver/chromedriver_win32/chromedriver.exe')
#driver = webdriver.Chrome(executable_path=r'pathtochromedriver/chromedriver_win32/chromedriver.exe')
driver = webdriver.Chrome('pathtochromedriver/chromedriver_win32/chromedriver.exe')
#
#loop
for group in gdf['Group Name'].unique():
    map_1km_json = json.loads(gdf[gdf['Group Name']==group].to_json())
    map_1km_data = alt.Data(values=map_1km_json['features'])
    data_1km_geojson = alt.InlineData(values=map_1km, format=alt.DataFormat(property='features',type='json'))
    domain=[1,2]
    range_=['#b0d247','#007bd1']
    choro1_5 = alt.Chart(map_1km_data).mark_geoshape().encode(
        alt.Color('properties.Cat2:O', scale=alt.Scale(domain=domain, range=range_),title = "Havvandsstigning"),
        #alt.Color('properties.Cat2', type='quantitative', scale=alt.Scale(scheme='plasma'),title = "Havvandsstigning")
        tooltip = ['properties.dd_km1:N','properties.Cat2:N']
    ).properties(
    width=1100,
    height=800
    )
    (background + choro1_5).save("{}.svg".format(bank))
driver.quit()

Running the code opens an empty new chrome pane (in the background) that looks like this, which hints to the fact that the chromedriver is working smoothly:运行代码会打开一个空的新 chrome 窗格(在后台),看起来像这样,这暗示了 chromedriver 工作顺利的事实: 铬板

But the code returns the following error:但是代码返回以下错误:

---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
~\Anaconda3\lib\site-packages\selenium\webdriver\common\service.py in start(self)
     75                                             stderr=self.log_file,
---> 76                                             stdin=PIPE)
     77         except TypeError:

~\Anaconda3\lib\subprocess.py in __init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, encoding, errors, text)
    774                                 errread, errwrite,
--> 775                                 restore_signals, start_new_session)
    776         except:

~\Anaconda3\lib\subprocess.py in _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, unused_restore_signals, unused_start_new_session)
   1177                                          os.fspath(cwd) if cwd is not None else None,
-> 1178                                          startupinfo)
   1179             finally:

FileNotFoundError: [WinError 2] The system cannot find the file specified

During handling of the above exception, another exception occurred:

WebDriverException                        Traceback (most recent call last)
<ipython-input-27-6067387e4b2f> in <module>
     19     height=800
     20     )
---> 21     (background + choro1_5).save("{}.svg".format(bank))
     22 driver.quit()

~\Anaconda3\lib\site-packages\altair\vegalite\v3\api.py in save(self, fp, format, override_data_transformer, scale_factor, vegalite_version, vega_version, vegaembed_version, **kwargs)
    478         if override_data_transformer:
    479             with data_transformers.disable_max_rows():
--> 480                 result = save(**kwds)
    481         else:
    482             result = save(**kwds)

~\Anaconda3\lib\site-packages\altair\utils\save.py in save(chart, fp, vega_version, vegaembed_version, format, mode, vegalite_version, embed_options, json_kwds, webdriver, scale_factor, **kwargs)
    102                                         vegaembed_version=vegaembed_version,
    103                                         webdriver=webdriver,
--> 104                                         scale_factor=scale_factor, **kwargs)
    105         if format == 'png':
    106             write_file_or_filename(fp, mimebundle['image/png'], mode='wb')

~\Anaconda3\lib\site-packages\altair\utils\mimebundle.py in spec_to_mimebundle(spec, format, mode, vega_version, vegaembed_version, vegalite_version, **kwargs)
     54                               vega_version=vega_version,
     55                               vegaembed_version=vegaembed_version,
---> 56                               vegalite_version=vegalite_version, **kwargs)
     57         if format == 'png':
     58             render = base64.b64decode(render.split(',', 1)[1].encode())

~\Anaconda3\lib\site-packages\altair\utils\headless.py in compile_spec(spec, format, mode, vega_version, vegaembed_version, vegalite_version, scale_factor, driver_timeout, webdriver)
    152             webdriver_options.add_argument('--no-sandbox')
    153 
--> 154     driver = webdriver_class(options=webdriver_options)
    155 
    156     try:

~\Anaconda3\lib\site-packages\selenium\webdriver\chrome\webdriver.py in __init__(self, executable_path, port, options, service_args, desired_capabilities, service_log_path, chrome_options, keep_alive)
     71             service_args=service_args,
     72             log_path=service_log_path)
---> 73         self.service.start()
     74 
     75         try:

~\Anaconda3\lib\site-packages\selenium\webdriver\common\service.py in start(self)
     81                 raise WebDriverException(
     82                     "'%s' executable needs to be in PATH. %s" % (
---> 83                         os.path.basename(self.path), self.start_error_message)
     84                 )
     85             elif err.errno == errno.EACCES:

WebDriverException: Message: 'chromedriver' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home

The reason your code does not work is because you are not passing your driver instance to Altair, and so Altair is creating a default driver instance and looking for chromedriver in the default location.您的代码不起作用的原因是您没有将驱动程序实例传递给 Altair,因此 Altair 正在创建默认驱动程序实例并在默认位置查找 chromedriver。

Altair currently does not support passing a custom driver instance to the save() method, so saving a figure in the way you are attempting above is not possible, unless chromedriver can be made available at the default location. Altair 当前不支持将自定义驱动程序实例传递给save()方法,因此无法以上述方式保存图形,除非可以在默认位置使用 chromedriver。

We are in the process of improving this, however, with the altair_saver package.但是,我们正在使用altair_saver包对此进行改进。 With it, you can pass a custom driver instance to the save method:有了它,您可以将自定义驱动程序实例传递给 save 方法:

from altair_saver import save

# ...

chart = background + choro1_5
filename = f"{bank}.svg"
save(chart, filename, method='selenium', webdriver=driver)

In a future Altair release, this more flexible saver extension will replace Altair's current built-in chart.save() method.在未来的 Altair 版本中,这个更灵活的保护程序扩展将取代 Altair 当前的内置chart.save()方法。

Have a look at Altair Saver project.看看Altair Saver项目。 It uses Chrome Driver and Selenium.它使用 Chrome 驱动程序和 Selenium。 Install via pip or conda.通过 pip 或 conda 安装。 It can save to svg:它可以保存到 svg:

from altair_saver import save

save((background + choro1_5), "{}.svg".format(bank))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM