mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-28 21:12:16 +00:00
Merge remote-tracking branch 'origin/main' into release/4.3.3
This commit is contained in:
1
openbb_platform/core/poetry.lock
generated
vendored
1
openbb_platform/core/poetry.lock
generated
vendored
@@ -1162,6 +1162,7 @@ typing-extensions = [
|
||||
{version = ">=4.12.2", markers = "python_version >= \"3.13\""},
|
||||
{version = ">=4.6.1", markers = "python_version < \"3.13\""},
|
||||
]
|
||||
tzdata = {version = "*", markers = "python_version >= \"3.9\""}
|
||||
|
||||
[package.extras]
|
||||
email = ["email-validator (>=2.0.0)"]
|
||||
|
||||
@@ -531,3 +531,210 @@ class EconomyViews:
|
||||
content = fig.to_plotly_json()
|
||||
|
||||
return fig, content
|
||||
|
||||
@staticmethod
|
||||
def economy_survey_bls_series(
|
||||
**kwargs,
|
||||
) -> Tuple["OpenBBFigure", Dict[str, Any]]:
|
||||
"""Economy Survey BLS Series Chart.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
data: Optional[Union[DataFrame, List[Data]]]
|
||||
Filtered subset of the parent results.
|
||||
target_symbol: Optional[str]
|
||||
The target symbol(s) to plot. Plot multiple symbols by separating them with a comma. Max 10 symbols.
|
||||
target_col: Optional[str]
|
||||
The target column to plot. Default is 'value'.
|
||||
plot_type: Literal["line", "bar"]
|
||||
The type of plot to display. Default is 'line', unless the data is significantly small.
|
||||
normalize: bool
|
||||
Normalize the data before displaying. Default is False.
|
||||
title: Optional[str]
|
||||
The title of the chart.
|
||||
xtitle: Optional[str]
|
||||
The title of the x-axis.
|
||||
ytitle: Optional[str]
|
||||
The title of the y-axis.
|
||||
bar_kwargs: Optional[Dict]
|
||||
Additional keyword arguments applied to `fig.add_bar`.
|
||||
scatter_kwargs: Optional[Dict]
|
||||
Additional keyword arguments applied to `fig.add_scatter`.
|
||||
layout_kwargs: Optional[Dict]
|
||||
Additional keyword arguments applied to `fig.update_layout`.
|
||||
"""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from openbb_charting.charts.generic_charts import bar_chart, line_chart
|
||||
from openbb_charting.charts.helpers import (
|
||||
z_score_standardization,
|
||||
)
|
||||
from openbb_core.app.utils import basemodel_to_df
|
||||
from pandas import DataFrame
|
||||
|
||||
provider = kwargs.get("provider")
|
||||
|
||||
if provider != "bls":
|
||||
raise RuntimeError(
|
||||
f"This charting method does not support {provider}. Supported providers: bls."
|
||||
)
|
||||
|
||||
_data = (
|
||||
kwargs.pop("data", None)
|
||||
if "data" in kwargs and kwargs["data"] is not None
|
||||
else kwargs.get("obbject_item")
|
||||
)
|
||||
df = DataFrame()
|
||||
|
||||
if isinstance(_data, DataFrame) and not _data.empty:
|
||||
df = _data.reset_index() if _data.index.name == "date" else _data
|
||||
else:
|
||||
try:
|
||||
df = basemodel_to_df(_data, index=None) # type: ignore
|
||||
except Exception as e:
|
||||
raise RuntimeError("Unable to process supplied data.") from e
|
||||
|
||||
if df.empty or len(df) < 2:
|
||||
raise RuntimeError("No data found to plot.")
|
||||
|
||||
cols = df.columns.to_list()
|
||||
target_col = kwargs.get("target_col", "value")
|
||||
if target_col not in cols:
|
||||
raise RuntimeError(f"Column '{target_col}' not found in the data.")
|
||||
|
||||
new_df = df.pivot(columns="symbol", values=target_col, index="date")
|
||||
target_symbols = kwargs.get("target_symbol", "").split(",")[:10] # type: ignore
|
||||
|
||||
if not target_symbols or len(target_symbols) == 0 or target_symbols[0] == "":
|
||||
target_symbols = new_df.columns.to_list()[:10]
|
||||
|
||||
metadata = kwargs["extra"].get("results_metadata", {}) # type: ignore
|
||||
ytitle = kwargs.get("ytitle", "")
|
||||
|
||||
new_df = new_df.filter(target_symbols, axis=1)
|
||||
|
||||
if "percent" in target_col.lower(): # type: ignore
|
||||
ytitle = (
|
||||
ytitle
|
||||
if ytitle
|
||||
else target_col.replace("change_percent_", "").replace("M", " Month") # type: ignore
|
||||
+ " Change (%)"
|
||||
)
|
||||
new_df = new_df.apply(lambda x: x * 100)
|
||||
elif "change" in target_col.lower() and "percent" not in target_col.lower(): # type: ignore
|
||||
ytitle = (
|
||||
ytitle
|
||||
if ytitle
|
||||
else target_col.replace("change_", "").replace("M", " Month") # type: ignore
|
||||
+ " Change"
|
||||
)
|
||||
|
||||
title_map: Dict = {}
|
||||
for symbol in target_symbols:
|
||||
if symbol not in new_df.columns:
|
||||
continue
|
||||
survey_name = metadata.get(symbol, {}).get("survey_name", symbol) # type: ignore
|
||||
series_title = metadata.get(symbol, {}).get("series_title", symbol) # type: ignore
|
||||
|
||||
if survey_name != series_title:
|
||||
title_map[symbol] = f"{survey_name} \n {series_title}"
|
||||
|
||||
normalize = kwargs.get("normalize", False)
|
||||
same_axis = kwargs.get("same_axis", False)
|
||||
|
||||
if normalize:
|
||||
new_df = new_df.apply(z_score_standardization)
|
||||
same_axis = True
|
||||
if ytitle:
|
||||
ytitle = f"Normalized {ytitle.replace('(%)', '')}" # type: ignore
|
||||
|
||||
plot_type = kwargs.get("plot_type")
|
||||
|
||||
if plot_type is None:
|
||||
plot_type = (
|
||||
"line" # type: ignore
|
||||
if (len(new_df.index) > 36 and len(new_df.columns.to_list()) >= 1)
|
||||
else "bar"
|
||||
)
|
||||
|
||||
layout_kwargs: Dict = kwargs.pop("layout_kwargs", {}) # type: ignore
|
||||
scatter_kwargs: Dict = kwargs.pop("scatter_kwargs", {}) # type: ignore
|
||||
bar_kwargs: Dict = kwargs.pop("bar_kwargs", {}) # type: ignore
|
||||
hovertemplate = scatter_kwargs.pop("hovertemplate", None) # type: ignore
|
||||
trace_titles = {
|
||||
symbol: metadata.get(symbol, {})
|
||||
.get("series_title", symbol)
|
||||
.replace(",", " -")
|
||||
for symbol in target_symbols
|
||||
}
|
||||
new_df.columns = [trace_titles.get(col, col) for col in new_df.columns]
|
||||
scatter_kwargs["hovertemplate"] = ( # type: ignore
|
||||
hovertemplate if hovertemplate else "%{fullData.name}:%{y}<extra></extra>"
|
||||
)
|
||||
|
||||
if len(target_symbols) == 1:
|
||||
title = title_map.get(target_symbols[0], target_symbols[0])
|
||||
fig = (
|
||||
line_chart(
|
||||
data=new_df,
|
||||
title=title,
|
||||
ytitle=ytitle,
|
||||
y=list(trace_titles.values()),
|
||||
scatter_kwargs=scatter_kwargs,
|
||||
layout_kwargs=layout_kwargs,
|
||||
**kwargs,
|
||||
)
|
||||
if plot_type == "line"
|
||||
else bar_chart(
|
||||
data=new_df,
|
||||
title=title,
|
||||
ytitle=ytitle,
|
||||
x=new_df.index,
|
||||
y=list(trace_titles.values()),
|
||||
layout_kwargs=layout_kwargs,
|
||||
bar_kwargs=bar_kwargs,
|
||||
**kwargs,
|
||||
)
|
||||
)
|
||||
else:
|
||||
survey_name = metadata.get(target_symbols[0], {}).get("survey_name", target_symbols[0]).split("\n")[0].strip() # type: ignore
|
||||
_t = kwargs.pop("title", None)
|
||||
title = _t if _t else f"{survey_name} - {ytitle}" if ytitle else survey_name
|
||||
fig = (
|
||||
line_chart(
|
||||
data=new_df,
|
||||
y=list(trace_titles.values()),
|
||||
title=title,
|
||||
ytitle=ytitle,
|
||||
same_axis=same_axis,
|
||||
normalize=False,
|
||||
scatter_kwargs=scatter_kwargs,
|
||||
layout_kwargs=layout_kwargs,
|
||||
**kwargs,
|
||||
)
|
||||
if plot_type == "line"
|
||||
else bar_chart(
|
||||
data=new_df,
|
||||
title=title,
|
||||
ytitle=ytitle,
|
||||
x=new_df.index,
|
||||
y=list(trace_titles.values()),
|
||||
layout_kwargs=layout_kwargs,
|
||||
bar_kwargs=bar_kwargs,
|
||||
**kwargs,
|
||||
)
|
||||
)
|
||||
|
||||
fig.update_layout(
|
||||
margin=dict(b=20),
|
||||
legend=dict(
|
||||
orientation="h",
|
||||
yanchor="top",
|
||||
xanchor="left",
|
||||
y=-0.075,
|
||||
x=0,
|
||||
font=dict(size=12),
|
||||
),
|
||||
)
|
||||
content = fig.to_plotly_json()
|
||||
|
||||
return fig, content
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1
openbb_platform/poetry.lock
generated
vendored
1
openbb_platform/poetry.lock
generated
vendored
@@ -2609,6 +2609,7 @@ files = [
|
||||
annotated-types = ">=0.6.0"
|
||||
pydantic-core = "2.23.4"
|
||||
typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""}
|
||||
tzdata = {version = "*", markers = "python_version >= \"3.9\""}
|
||||
|
||||
[package.extras]
|
||||
email = ["email-validator (>=2.0.0)"]
|
||||
|
||||
Reference in New Issue
Block a user