Loading...
Loading...
Best practices for doing quick exploratory data analysis with minimal code and a Pandas .plot like API using HoloViews hvPlot.
npx skill4agent add marcskovmadsen/holoviz-mcp hvplothvplotpip install hvplot hvsampledata panel watchfilesearthquakesimport hvsampledata
hvsampledata.earthquakes("pandas")Tabular record of earthquake events from the USGS Earthquake Catalog that provides detailed
information including parameters such as time, location as latitude/longitude coordinates
and place name, depth, and magnitude. The dataset contains 596 events.
Note: The columns `depth_class` and `mag_class` were created by categorizing numerical values from
the `depth` and `mag` columns in the original dataset using custom-defined binning:
Depth Classification
| depth | depth_class |
|-----------|--------------|
| Below 70 | Shallow |
| 70 - 300 | Intermediate |
| Above 300 | Deep |
Magnitude Classification
| mag | mag_class |
|-------------|-----------|
| 3.9 - <4.9 | Light |
| 4.9 - <5.9 | Moderate |
| 5.9 - <6.9 | Strong |
| 6.9 - <7.9 | Major |
Schema
------
| name | type | description |
|:------------|:-----------|:--------------------------------------------------------------------|
| time | datetime | UTC Time when the event occurred. |
| lat | float | Decimal degrees latitude. Negative values for southern latitudes. |
| lon | float | Decimal degrees longitude. Negative values for western longitudes |
| depth | float | Depth of the event in kilometers. |
| depth_class | category | The depth category derived from the depth column. |
| mag | float | The magnitude for the event. |
| mag_class | category | The magnitude category derived from the mag column. |
| place | string | Textual description of named geographic region near to the event. |import hvsampledata
# DO import panel if working in .py files
import panel as pn
# Do importing hvplot.pandas to add .hvplot namespace to Pandas DataFrames and Series
import hvplot.pandas # noqa: F401
# DO always run pn.extension() to load panel javascript extensions
pn.extension()
# Do keep the extraction, transformation and plotting of data clearly separate
# Extract: earthquakes sample data
data = hvsampledata.earthquakes("pandas")
# Transform: Group by mag_class and count occurrences
mag_class_counts = data.groupby('mag_class').size().reset_index(name='counts')
# Plot: counts by mag_class
plot = mag_class_counts.hvplot.bar(x='mag_class', y='counts', title='Earthquake Counts by Magnitude Class')
# If working in notebook DO output to plot:
plot
# Else if working in .py file DO:
# DO provide a method to serve the app with `panel serve`
if pn.state.served:
# DO remember to add .servable to the panel components you want to serve with the app
pn.panel(plot, sizing_mode="stretch_both").servable()
# DON'T provide a `if __name__ == "__main__":` method to serve the app with `python`panel serve path/to/file.py --dev --showpython path_to_this_file.pyimport hvplot.pandas # will add .hvplot namespace to Pandas dataframes
import hvplot.polars # will add .hvplot namespace to Polars dataframes
...from bokeh.models.formatters import NumeralTickFormatter
df.hvplot(
...,
yformatter=NumeralTickFormatter(format='0.00a'), # Format as 1.00M, 2.50M, etc.
)| Input | Format String | Output |
|---|---|---|
| 1230974 | '0.0a' | 1.2m |
| 1460 | '0 a' | 1 k |
| -104000 | '0a' | -104k |
import pandas as pd
import hvplot.pandas # noqa
import panel as pn
import numpy as np
np.random.seed(42)
dates = pd.date_range("2022-08-01", periods=30, freq="B")
open_prices = np.cumsum(np.random.normal(100, 2, size=len(dates)))
high_prices = open_prices + np.random.uniform(1, 5, size=len(dates))
low_prices = open_prices - np.random.uniform(1, 5, size=len(dates))
close_prices = open_prices + np.random.uniform(-3, 3, size=len(dates))
data = pd.DataFrame({
"open": open_prices.round(2),
"high": high_prices.round(2),
"low": low_prices.round(2),
"close": close_prices.round(2),
}, index=dates)
# Create a scatter plot of date vs close price
scatter_plot = data.hvplot.scatter(x="index", y="close", grid=True, title="Close Price Scatter Plot", xlabel="Date", ylabel="Close Price")
# Create a Panel app
app = pn.Column("# Close Price Scatter Plot", scatter_plot)
if pn.state.served:
app.servable()panel serve plot.py --devsearchhvplot_listhvplot_getskill_getholoviz-mcphvholoviz-mcp searchholoviz-mcp hvplot listholoviz-mcp hvplot getstreamingtestspytest tests/path/to/test_file.pypanel serve path_to_file.py --dev --show--show--dev--port {port-number}--autoreloadpython path_to_file.pypn.Column, pn.Tabs, pn.Accordion