<jupyter_start><jupyter_text>Tutorial 3: Data Visualizations[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/niconoe/pyinaturalist/main?filepath=examples%2FTutorial_3_Data_Visualizations.ipynb)This notebook will show you a few basic visualizations you can make with your own observation data.We'll do this with [Pandas](https://pandas.pydata.org/docs/getting_started/index.html) and [Altair](https://altair-viz.github.io). Don't worry if you're not familiar with those tools, this is just to demonstrate the kinds of things you can do with your data.<jupyter_code>from datetime import datetime, timedelta

import altair as alt
import pandas as pd
from dateutil.relativedelta import relativedelta
from pyinaturalist import Observation, enable_logging, get_observations, pprint
from rich import print

enable_logging()<jupyter_output><empty_output><jupyter_text>Observation dataWe'll start with all of your own observation data from the last 3 years:<jupyter_code># Replace with your own username
USERNAME = 'jkcook'

start_date = datetime.now() - timedelta(365 * 3)
response = get_observations(user_id=USERNAME, d1=start_date, page='all')
my_observations = Observation.from_json_list(response)
pprint(my_observations[:10])<jupyter_output><empty_output><jupyter_text>Basic historgamNext, let's make a simple histogram to show your observations over time.Start by putting your observations into a DataFrame to make them easier to work with:<jupyter_code>source = pd.DataFrame([{'date': o.observed_on.isoformat()} for o in my_observations])<jupyter_output><empty_output><jupyter_text>And then display it as a bar chart:<jupyter_code>(
    alt.Chart(source)
    .mark_bar()
    .properties(width=700, height=500)
    .encode(
        x='yearmonth(date):T',
        y=alt.Y(
            'count()',
            scale=alt.Scale(type='log'),
            axis=alt.Axis(title='Number of observations'),
        ),
    )
)<jupyter_output><empty_output><jupyter_text>Histogram by iconic taxonTo show a bit more information, let's break down the observations by category (iconic taxon):<jupyter_code>source = pd.DataFrame(
    [
        {'date': o.observed_on.isoformat(), 'iconic_taxon': o.taxon.iconic_taxon_name}
        for o in my_observations
    ]
)
(
    alt.Chart(source)
    .mark_bar()
    .properties(width=700, height=500)
    .encode(
        x='yearmonth(date):T',
        y=alt.Y(
            'count()',
            scale=alt.Scale(type='symlog'),
            axis=alt.Axis(title='Number of observations'),
        ),
        color='iconic_taxon',
    )
)<jupyter_output><empty_output><jupyter_text>Observation mapNext, we can show the observations on a map. **Note:** This example only shows observations in the United States.First, get the coordinates for all your observations, skipping any that are missing locatino info:<jupyter_code>source = pd.DataFrame(
    [
        {
            'latitude': o.location[0],
            'longitude': o.location[1],
            'iconic_taxon': o.taxon.iconic_taxon_name,
        }
        for o in my_observations
        if o.location
    ]
)<jupyter_output><empty_output><jupyter_text>Then add the base layer. This example uses the `us_10m` dataset from [vega-datasets](https://github.com/vega/vega-datasets):<jupyter_code>from vega_datasets import data

states = alt.topo_feature(data.us_10m.url, feature='states')
background = (
    alt.Chart(states)
    .mark_geoshape(fill='lightgray', stroke='white')
    .properties(width=850, height=500)
    .project('albersUsa')
)<jupyter_output><empty_output><jupyter_text>And finally, add your observation locations:<jupyter_code>points = (
    alt.Chart(source)
    .mark_circle()
    .encode(
        longitude='longitude:Q',
        latitude='latitude:Q',
    )
)

# Show the combined background + points
background + points<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1123160340821069, 'fraction_numerical': 0.009295120061967466, 'mean_word_length': 4.328748280605227, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 5, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '434347', 'license': 'MIT', 'n_tokens_mistral': 1284, 'n_tokens_neox': 1238, 'n_words': 292, 'path': 'examples/Tutorial_3_Data_Visualizations.ipynb', 'repo_name': 'niconoe/pyinaturalist', 'size': '3873'}