Ejemplo n.º 1
0
import altair as alt
from vega_datasets import data
import geopandas as gpd

df_quakes = gpd.read_file("lastday.json")
df_quakes = df_quakes[df_quakes["mag"] != "-"]
df_quakes["mag_num"] = df_quakes["mag"].astype(float)
df_quakes = df_quakes[df_quakes.mag_num > 0]

# Data generators for the background
sphere = alt.sphere()
graticule = alt.graticule()

# Source of land data
# source = alt.topo_feature(data.world_110m.url, 'countries')
source = gpd.read_file("AT_and_neighbors.geojson")

# Layering and configuring the components
background = alt.Chart(source).mark_geoshape(fill='lightgrey', stroke='white')
points = alt.Chart(df_quakes).mark_circle().encode(
    longitude="lon:Q",
    latitude="lat:Q",
    #size=alt.Size("mag_num:Q", title="Magnitude"),
    #size="magmag:Q",
    color="red",
    fillOpacity=0.5
    # ).transform_calculate(
    #     magmag="int(10*datum.mag)"
).project(
    type='conicConformal',
    center=[8, -3],
Ejemplo n.º 2
0
# --- Graticule Generator

import altair as alt

data = alt.graticule(step=[15, 15])

alt.Chart(data).mark_geoshape(stroke='black').project(
    'orthographic',
    rotate=[0, -45, 0]
)

# --- Sphere Generator
import altair as alt

sphere_data = alt.sphere()
grat_data = alt.graticule(step=[15, 15])

background = alt.Chart(sphere_data).mark_geoshape(fill='aliceblue')
lines = alt.Chart(grat_data).mark_geoshape(stroke='lightgrey')

alt.layer(background, lines).project('naturalEarth1')


######## ---------
#
# Encodings

import altair as alt
from vega_datasets import data
cars = data.cars()
def write():
    st.header("FIFA Players Across the World")
    st.write("""Let's explore the distribution of footballers around the world.
                Hover over the map to see player stats for different countries
                grouped by player nationality.""")

    # Load in the data
    fifa_country_agg = load_data('data/clean_fifa_country_aggs.csv')
    continents_zoom_params = load_continent_zoom_params()
    continents = list(continents_zoom_params.keys())

    # Add sliders and checkboxes for users to configure visualization
    player_stats_dict, player_stats_labels, player_stats_columns = load_player_stats(
    )
    agg_functions = ['Mean', 'Min', 'Max']

    # Show results for top N countries
    num_countries = fifa_country_agg.shape[0]
    st.markdown('### Show Top N Countries')
    top_countries_count = st.slider('N', 0, num_countries, num_countries)

    # Select continent to zoom into on map
    select_continent = st.selectbox('Continent',
                                    options=continents,
                                    index=continents.index('All'))
    st.subheader("Map: %s" % select_continent)

    # Select which player stats to show
    st.sidebar.markdown('### Show Player Stats')
    show_player_stats = st.sidebar.multiselect(
        'Show in Tooltip and Table',
        options=player_stats_labels,
        default=['Age', 'Overall Rating (0-100)', 'Potential Rating (0-100)'])

    # Select which aggregate functions to include
    st.sidebar.markdown('### Show Aggregate Functions')
    agg_functions_checkbox = {}
    for a in agg_functions:
        agg_functions_checkbox[a] = st.sidebar.checkbox(a, value=a in ['Mean'])

    # Select how to determine top N countries
    st.sidebar.markdown('### Top N Countries Based On')
    top_countries_attr = st.sidebar.selectbox('Player Stat',
                                              options=player_stats_labels,
                                              index=3)
    top_countries_agg = st.sidebar.selectbox('Using', options=agg_functions)
    top_countries_order = st.sidebar.selectbox(
        'Order', options=['Ascending', 'Descending'], index=1)

    # Draw the world map of FIFA 19 player nationalities
    # source: https://altair-viz.github.io/gallery/index.html#maps

    # Data to show based on user selections
    show_df = fifa_country_agg.sort_values(
        by='%s_%s' %
        (player_stats_dict.get(top_countries_attr), top_countries_agg.lower()),
        ascending=top_countries_order == 'Ascending').head(top_countries_count)

    # Data generators for the background
    sphere = alt.sphere()
    graticule = alt.graticule()

    # Source of land data
    source = alt.topo_feature(data.world_110m.url, 'countries')

    # Layering and configuring the components
    background = alt.layer(
        alt.Chart(sphere).mark_geoshape(fill='lightblue'),
        alt.Chart(graticule).mark_geoshape(stroke='white', strokeWidth=0.2),
        alt.Chart(source).mark_geoshape(
            fill='#9eb5a8', stroke='black')).project(
                type='equirectangular',  # map type
                scale=continents_zoom_params.get(select_continent)[0],
                center=continents_zoom_params.get(select_continent)
                [1:3]).properties(width=800,
                                  height=400).configure_view(stroke=None)

    hover = alt.selection(type='single',
                          on='mouseover',
                          nearest=True,
                          fields=['Latitude', 'Longitude'])

    # Get fields to show in tooltip
    tooltip_info = ['Nationality Country']
    for player_stat_label in show_player_stats:
        player_stat_column = player_stats_dict.get(player_stat_label)
        for agg_function, function_checked in agg_functions_checkbox.items():
            if function_checked:
                tooltip_info.append("%s_%s" %
                                    (player_stat_column, agg_function.lower()))

    base = alt.Chart(show_df).encode(longitude='Longitude:Q',
                                     latitude='Latitude:Q',
                                     tooltip=tooltip_info)

    points = base.mark_point().encode(
        color=alt.condition(~hover, alt.value('#014600'), alt.value('red')),
        size=alt.condition(~hover, alt.value(30),
                           alt.value(100))).add_selection(hover)

    st.write(background + points)

    st.subheader("Data Shown on Map")
    st.write(show_df[tooltip_info])
Ejemplo n.º 4
0
def plot_all(dataset=f"data/{_OUTPUT_JSON_FILENAME}"):
    """
    Function to plot all available maps and charts that interact.

    Available charts and maps:
        plot_stats_world
        plot_tweets_world
        plot_stats_usa
        plot_tweets_usa
        plot_choro_usa

    Args:
        dataset: JSON formatted file with tweet data.
            Defaults to "data/_OUTPUT_JSON_FILENAME".

    Returns:
        output_map: Collection of all maps and charts.
    """
    try:
        # calling utility functions to create dataframes
        df_world = create_dataframe_world(dataset)
        df_usa = create_dataframe_us(dataset)
        choro = create_dataframe_choropleth(dataset)

        # using vega_datasets(data)
        countries = alt.topo_feature(data.world_110m.url, feature='countries')
        states = alt.topo_feature(data.us_10m.url, feature="states")
        # using altair function to create a spherical background
        sphere = alt.sphere()

        # setting variables for interaction
        # setting actual selection
        brush = alt.selection_multi(encodings=["y"])
        # setting the opacity of (un)selected bars
        opacity_overview = alt.condition(brush, alt.value(0.9), alt.value(0.1))
        # setting the opacity of (un)selected points
        opacity_points = alt.condition(brush, alt.value(1), alt.value(0))

        # disable the max rows restriction to be able to chart larger datasets
        alt.data_transformers.disable_max_rows()

        # spheric background
        spheric_background = alt.Chart(sphere).mark_geoshape(fill="aliceblue")

        # us-states background
        background_usa = alt.Chart(states).mark_geoshape(
            fill="lightgray",
            stroke="white"
        ).properties(
            width=720,
            height=400
        )

        # world countries background
        background_world = alt.Chart(countries).mark_geoshape(
            fill='lightgray',
            stroke='white'
        ).properties(
            width=720,
            height=400
        )

        # plot_tweets_world()
        tweets_world = alt.Chart(df_world).mark_square(
            size=1, opacity=0.8).encode(
                longitude="coord_lon",
                latitude="coord_lat",
                color=alt.Color("sentiment:N",
                                scale=alt.Scale(
                                    domain=["positive", "neutral", 'negative'],
                                    range=["green", "orange", "red"],
                                )
                                ),
            tooltip=["user_name", "text", "sentiment"],
            opacity=opacity_points
        ).add_selection(brush).properties(title="Tweets of the world")

        # plot_tweets_usa()
        tweets_usa = alt.Chart(df_usa).mark_square(size=5, opacity=0.5).encode(
            longitude="coord_lon",
            latitude="coord_lat",
            color=alt.Color("sentiment:N",
                            scale=alt.Scale(
                                domain=["positive", "neutral", "negative"],
                                range=["green", "orange", "red"]
                            )
                            ),
            tooltip=["user_name", "text", "sentiment"],
            opacity=opacity_points
        ).add_selection(brush).properties(title="Tweets of the US")

        # plot_stats_world()
        stats_world = alt.Chart(df_world).mark_bar().encode(
            alt.Y("source_clean:N",
                  title="sources"
                  ),
            alt.X("count()"),
            opacity=opacity_overview,
            tooltip="count()"
        ).add_selection(
            brush
        ).properties(
            width=720,
            title="Tweet sources of the world"
        ).interactive()

        # plot_stats_usa()
        stats_usa = alt.Chart(df_usa).mark_bar().encode(
            alt.Y("source_clean:N",
                  title="sources"
                  ),
            alt.X("count()"),
            opacity=opacity_overview,
            tooltip="count()"
        ).add_selection(
            brush
        ).properties(
            width=720,
            title="Tweet sources of the US"
        ).interactive()

        # plot_choro_usa()
        choro = alt.Chart(choro).mark_geoshape().encode(
            color=alt.Color('sentiment',
                            legend=alt.Legend(title="Positivity",
                                              tickCount=5,
                                              tickMinStep=0.5),
                            scale=alt.Scale(
                                scheme='redyellowgreen', domain=[-1, 1])
                            ),
            tooltip=["name:N", "sentiment"]
        ).properties(
            width=720,
            height=400,
            title="Average tweet sentiment per state of the US"
        ).add_selection(brush)

        # generating the final layered chart
        output_map = stats_world &\
            (spheric_background + background_world + tweets_world).project(
                "naturalEarth1") &\
            stats_usa &\
            (background_usa + tweets_usa).project("albersUsa") &\
            (background_usa + choro).project("albersUsa")

        return output_map

    except Exception:
        raise ValueError("""There are no tweets in the dataset yet!
            Try running get_data() again to collect more data or
            select another dataset.""")
Ejemplo n.º 5
0
def plot_tweets_world(dataset=f"data/{_OUTPUT_JSON_FILENAME}"):
    """
    Function to plot all tweets worldwide as points using altair.

    Args:
        dataset: JSON formatted file with tweet data.
            Defaults to "data/_OUTPUT_JSON_FILENAME".

    Returns:
        output_map: map that represents the world and all tweets.

    Raises:
        ValueError: If no tweets can be found in the dataset.
    """
    try:
        # calling utility function to create dataframe
        df = create_dataframe_world(dataset)
        # using vega_datasets(data) to get the borders of the countries
        countries = alt.topo_feature(data.world_110m.url, feature='countries')
        # using altair function to create a spherical background
        sphere = alt.sphere()

        # disable the max rows restriction to be able to chart large datasets
        alt.data_transformers.disable_max_rows()

        # generating chart consisting of the spherical background
        spheric_background = alt.Chart(sphere).mark_geoshape(fill="aliceblue")

        # generating chart consisting of the countries
        background_world = alt.Chart(countries).mark_geoshape(
            fill='lightgray',
            stroke='white'
        ).properties(
            width=720,
            height=400
        )

        # generating chart consisting of the tweets
        points_world = alt.Chart(df).mark_square(size=1, opacity=0.8).encode(
            # setting the lat/lon
            longitude="coord_lon",
            latitude="coord_lat",
            color=alt.Color("sentiment:N",
                            # matching the classes onto the sentiment
                            scale=alt.Scale(domain=[
                                "positive", "neutral", 'negative'
                            ],
                                # colouring the classes
                                range=["green", "orange", "red"]
                            )
                            ),
            # generating tooltip with the user name, text, sentiment of tweet
            tooltip=["user_name", "text", "sentiment"]
        ).properties(title="Tweets of the world")

        # generating the final layered chart
        output_map = (spheric_background + background_world + points_world)\
            .project("naturalEarth1")

        return output_map

    except Exception:
        raise ValueError("""There are no tweets in the dataset yet!
            Try running get_data() again to collect more data or
            select another dataset.""")
Ejemplo n.º 6
0
def generate_countries_map(data: pd.DataFrame,
                           date,
                           interactive: bool = False,
                           width: int = 600,
                           height: int = 600,
                           log_scale: bool = True) -> alt.Chart:

    fechas = data['fecha'].apply(lambda x: x.date())
    data = data[(fechas == date)]

    scale = alt.Scale(type='log', scheme='teals') if log_scale else alt.Scale(
        type='linear', scheme='teals')
    url_country_name = 'https://raw.githubusercontent.com/alisle/world-110m-country-codes/master/world-110m-country-codes.json'

    country_names = pd.read_json(url_country_name).drop('name', axis=1)
    country_data = get_country_data()
    country_data = country_names.join((country_data.set_index('code')),
                                      on='code')

    data = pd.merge(left=country_data,
                    right=data,
                    left_on='name',
                    right_on='pais').dropna()
    data = data.astype({'id': int, 'casos': int})

    sphere = alt.sphere()
    graticule = alt.graticule()
    source = alt.topo_feature(vd.data.world_110m.url, 'countries')

    sphere_chart = alt.Chart(
        sphere,
        title='Ubicación de los casos confirmados por país').mark_geoshape(
            fill='lightblue')
    graticule_chart = alt.Chart(graticule).mark_geoshape(stroke='white',
                                                         strokeWidth=0.5)
    countries_chart = (alt.Chart(source).mark_geoshape().encode(
        color=alt.Color('casos:Q', title='Casos', scale=scale, legend=None),
        tooltip=[
            alt.Tooltip('name:N', title='País'),
            alt.Tooltip('code:N', title='Código'),
            alt.Tooltip('casos:Q', title='Casos')
        ]).transform_lookup('id',
                            from_=alt.LookupData(
                                data=data,
                                key='id',
                                fields=['code', 'name', 'casos'])))

    single = alt.selection_single(
        on='mouseover', nearest=True, fields=['pais'],
        empty='all') if interactive else alt.selection_single()

    circle_chart = (alt.Chart(source).mark_circle(
        opacity=0.4, color='red').encode(
            longitude='lon:Q',
            latitude='lat:Q',
            size=(alt.condition(
                single,
                alt.Size('casos:Q',
                         scale=alt.Scale(range=[50, 4000]),
                         legend=None), alt.value(0))),
            tooltip=[
                alt.Tooltip('pais:N', title='País'),
                alt.Tooltip('code:N', title='Código'),
                alt.Tooltip('casos:Q', title='Casos')
            ]).transform_lookup('id',
                                from_=alt.LookupData(data=data,
                                                     key='id',
                                                     fields=[
                                                         'code', 'pais',
                                                         'casos', 'lat', 'lon'
                                                     ])).add_selection(single))

    final_chart = ((sphere_chart + graticule_chart + countries_chart +
                    circle_chart).project('naturalEarth1').properties(
                        width=800, height=500).configure_view(stroke=None))

    return final_chart