2

I've made an altair scattered chart with links. It works perfectly from my Jupyter Notebook. Problems start when altair is in Streamlit environment. As I investigated, my app with altair chart is displayed by iframe. The link target cannot be displayed within iframe (server refuses these connections).

It all works properly when I Ctrl+Click the link and it opens in new tab. How can I make opening as a new tab a default here? I see this topic discussed here: https://github.com/altair-viz/altair/issues/1661 but I don't know how to use instructions included there :-(

How should I change my chart specification?

My chart code:

    import pandas as pd
import altair as alt

#Analyzed data is here:
URL='https://dl.dropboxusercontent.com/s/blk95gc1bf8errv/Car_Prices_Poland_BS4_1_0.csv'

tabela = pd.read_csv(URL)
tabela['calymodel'] = tabela['mark'] + ' ' + tabela['model']
calymodelunique = tabela['calymodel'].unique()
domyslny_model = calymodelunique.tolist().index('volkswagen passat')



auto = 'volkswagen passat'
auto_wiersze = tabela[tabela['calymodel']==auto]
marka_wybrana = auto.split()[0]
model_wybrany = auto.split()[1]


quant_cen = auto_wiersze['price'].quantile(q=0.99)
quant_mil = auto_wiersze['mileage'].quantile(q=0.99)

scattered = alt.Chart(auto_wiersze).mark_point().encode(
    x=alt.X('price',scale=alt.Scale(domain=(0,quant_cen),clamp=True), title='Cena [zł]'),
    y=alt.Y('mileage',scale=alt.Scale(domain=(0,quant_mil),clamp=True), title='Przebieg [km]'),
    color=alt.Color('year', scale=alt.Scale(scheme='tableau10'),bin=alt.Bin(maxbins=6),legend=alt.Legend(title="Przedziały roczników")),
    tooltip=[alt.Tooltip('year',title='Rocznik'),
            alt.Tooltip('mileage',title='Przebieg'),
            alt.Tooltip('price',title='Cena'),
            alt.Tooltip('link',title='Link')],
     href='link:N',
     
        
                       
).properties(title="Porównanie ceny w zależności od rocznika i przebiegu",     
    height=600)

scattered

For the moment I use Ctrl+Click to follow the link, but I don't think it's user friendly option.

My app is available here: https://share.streamlit.io/napierajpl/streamlit/bs4/streamlit1.py

You can see it crashes when you click on link on first chart :-( Otomoto.pl server reply is: Connection refused

Krzysztof Dołęgowski
  • 2,583
  • 1
  • 5
  • 21

1 Answers1

2

You can manually change the usermeta as described in the linked issue:

import altair as alt
from vega_datasets import data
from urllib.parse import urlencode


def make_google_query(name):
    return "https://www.google.com/search?" + urlencode({'q': '"{0}"'.format(name)})


cars = data.cars()
cars['url'] = cars['Name'].apply(make_google_query)

chart = alt.Chart(cars).mark_circle(size=60).encode(
    x='Horsepower',
    y='Miles_per_Gallon',
    color='Origin',
    href='url',
    tooltip=['Name', 'url']
)

chart['usermeta'] = {
    "embedOptions": {
        'loader': {'target': '_blank'}
    }
}
joelostblom
  • 43,590
  • 17
  • 150
  • 159
  • 1
    Hi, Thanks for this answer. In my case it solves half of the problem. When code is executed in Jupyter Notebook - it works great. But when it's displayed via Streamlit, it still does not open anything and returns error: connection refused. As I mentioned earlier, it might be a problem with iframe where everything is rendered. Otomoto.pl (target website) refuses to be displayed in iframe. – Krzysztof Dołęgowski May 14 '22 at 14:50
  • 1
    @KrzysztofDołęgowski That sounds like a problem outside of altair and possibly also outside streamlit. Now that you know how to change the `target` maybe you can experiment with other values such as `'_parent'` as mentioned here https://stackoverflow.com/questions/22808065/how-to-make-all-links-in-an-iframe-open-in-new-tab – joelostblom May 14 '22 at 15:53