mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 12:40:35 +00:00
Fix stocks asthetic style (#1355)
* Fix Theo's comment * Fix tests failing * Fix tests * Make plot lines thinner * Make ticks thinner globally by default * Apply global style when any controller is initialized Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com>
This commit is contained in:
@@ -27,6 +27,7 @@ from gamestonk_terminal.helper_funcs import (
|
||||
parse_known_args_and_warn,
|
||||
valid_date_in_past,
|
||||
)
|
||||
from gamestonk_terminal.config_terminal import theme
|
||||
from gamestonk_terminal.rich_config import console
|
||||
from gamestonk_terminal.stocks import stocks_helper
|
||||
from gamestonk_terminal.cryptocurrency import cryptocurrency_helpers
|
||||
@@ -94,6 +95,8 @@ class BaseController(metaclass=ABCMeta):
|
||||
)
|
||||
self.parser.add_argument("cmd", choices=self.controller_choices)
|
||||
|
||||
theme.applyMPLstyle()
|
||||
|
||||
def check_path(self) -> None:
|
||||
path = self.PATH
|
||||
if path[0] != "/":
|
||||
|
||||
@@ -64,8 +64,8 @@ def display_sentiment_compare(
|
||||
|
||||
for idx, tick in enumerate(similar):
|
||||
offset = 2 * idx
|
||||
ax.axhline(y=offset, color="grey", linestyle="--", lw=2)
|
||||
ax.axhline(y=offset + 1, color="grey", linestyle="--", lw=1)
|
||||
ax.axhline(y=offset, color="white", linestyle="--", lw=1)
|
||||
ax.axhline(y=offset + 1, color="white", linestyle="--", lw=1)
|
||||
|
||||
senValues = np.array(pd.to_numeric(df_sentiment[tick].values))
|
||||
senNone = np.array(0 * len(df_sentiment))
|
||||
@@ -74,7 +74,6 @@ def display_sentiment_compare(
|
||||
pd.to_numeric(df_sentiment[tick].values) + offset,
|
||||
offset,
|
||||
where=(senValues < senNone),
|
||||
alpha=0.60,
|
||||
color=theme.down_color,
|
||||
interpolate=True,
|
||||
)
|
||||
@@ -84,15 +83,13 @@ def display_sentiment_compare(
|
||||
pd.to_numeric(df_sentiment[tick].values) + offset,
|
||||
offset,
|
||||
where=(senValues >= senNone),
|
||||
alpha=0.60,
|
||||
color=theme.up_color,
|
||||
interpolate=True,
|
||||
)
|
||||
|
||||
ax.set_ylabel("Sentiment")
|
||||
ax.axhline(y=-1, color="grey", linestyle="--", lw=1)
|
||||
ax.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2)
|
||||
ax.minorticks_on()
|
||||
|
||||
ax.axhline(y=-1, color="white", linestyle="--", lw=1)
|
||||
ax.set_yticks(np.arange(len(similar)) * 2)
|
||||
ax.set_yticklabels(similar)
|
||||
ax.set_xlim(df_sentiment.index[0], df_sentiment.index[-1])
|
||||
@@ -172,7 +169,9 @@ def display_sentiment_correlation(
|
||||
ax=ax,
|
||||
)
|
||||
similar_string = ",".join(similar)
|
||||
ax.set_title(f"Correlation heatmap across {similar_string}")
|
||||
ax.set_title(
|
||||
f"Sentiment correlation heatmap across \n{similar_string}", fontsize=11
|
||||
)
|
||||
|
||||
if not external_axes:
|
||||
theme.visualize_output()
|
||||
|
||||
@@ -3,7 +3,7 @@ __docformat__ = "numpy"
|
||||
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
from typing import List
|
||||
from typing import List, Optional
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import pandas as pd
|
||||
@@ -11,10 +11,11 @@ import yfinance as yf
|
||||
from sklearn.manifold import TSNE
|
||||
from sklearn.preprocessing import normalize
|
||||
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
from gamestonk_terminal.config_terminal import theme
|
||||
from gamestonk_terminal.config_plot import PLOT_DPI
|
||||
from gamestonk_terminal.decorators import log_start_end
|
||||
from gamestonk_terminal.helper_funcs import plot_autoscale
|
||||
from gamestonk_terminal.rich_config import console
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -84,7 +85,11 @@ def get_1y_sp500() -> pd.DataFrame:
|
||||
|
||||
@log_start_end(log=logger)
|
||||
def get_sp500_comps_tsne(
|
||||
ticker: str, lr: int = 200, no_plot: bool = False, num_tickers: int = 10
|
||||
ticker: str,
|
||||
lr: int = 200,
|
||||
no_plot: bool = False,
|
||||
num_tickers: int = 10,
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
) -> List[str]:
|
||||
"""
|
||||
Runs TSNE on SP500 tickers (along with ticker if not in SP500).
|
||||
@@ -125,20 +130,61 @@ def get_sp500_comps_tsne(
|
||||
xs = tsne_features[:, 0]
|
||||
ys = tsne_features[:, 1]
|
||||
if not no_plot:
|
||||
fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
|
||||
ax.scatter(xs, ys, alpha=0.5)
|
||||
for x, y, company in zip(xs, ys, rets.index):
|
||||
if company != ticker:
|
||||
ax.annotate(company, (x, y), fontsize=9, alpha=0.75)
|
||||
else:
|
||||
ax.scatter(x, y, s=50, c="r")
|
||||
ax.annotate(company, (x, y), fontsize=9, alpha=1)
|
||||
fig.tight_layout()
|
||||
if gtff.USE_ION:
|
||||
plt.ion()
|
||||
plt.show()
|
||||
data = pd.DataFrame({"X": xs, "Y": ys}, index=rets.index)
|
||||
x0, y0 = data.loc[ticker]
|
||||
data["dist"] = (data.X - x0) ** 2 + (data.Y - y0) ** 2
|
||||
data = data.sort_values(by="dist")
|
||||
return data.iloc[1 : num_tickers + 1].index.to_list()
|
||||
# This plot has 1 axis
|
||||
if not external_axes:
|
||||
_, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
|
||||
else:
|
||||
if len(external_axes) != 1:
|
||||
console.print("[red]Expected list of one axis item./n[/red]")
|
||||
return []
|
||||
(ax,) = external_axes
|
||||
|
||||
data = pd.DataFrame({"X": xs, "Y": ys}, index=rets.index)
|
||||
x0, y0 = data.loc[ticker]
|
||||
data["dist"] = (data.X - x0) ** 2 + (data.Y - y0) ** 2
|
||||
data = data.sort_values(by="dist")
|
||||
ticker_df = data[data.index == ticker]
|
||||
|
||||
top_n = data.iloc[1 : (num_tickers + 1)]
|
||||
top_n_name = top_n.index.to_list()
|
||||
|
||||
top_100 = data[(num_tickers + 1) : 101]
|
||||
|
||||
ax.scatter(
|
||||
top_n.X,
|
||||
top_n.Y,
|
||||
alpha=0.8,
|
||||
c=theme.up_color,
|
||||
label=f"Top {num_tickers} closest tickers",
|
||||
)
|
||||
ax.scatter(
|
||||
top_100.X, top_100.Y, alpha=0.5, c="grey", label="Top 100 closest tickers"
|
||||
)
|
||||
|
||||
for x, y, company in zip(top_n.X, top_n.Y, top_n.index):
|
||||
ax.annotate(company, (x, y), fontsize=9, alpha=0.9)
|
||||
|
||||
for x, y, company in zip(top_100.X, top_100.Y, top_100.index):
|
||||
ax.annotate(company, (x, y), fontsize=9, alpha=0.75)
|
||||
|
||||
ax.scatter(
|
||||
ticker_df.X,
|
||||
ticker_df.Y,
|
||||
s=50,
|
||||
c=theme.down_color,
|
||||
)
|
||||
ax.annotate(ticker, (ticker_df.X, ticker_df.Y), fontsize=9, alpha=1)
|
||||
ax.legend()
|
||||
|
||||
ax.set_title(
|
||||
f"Top 100 closest stocks on S&P500 to {ticker} using TSNE algorithm",
|
||||
fontsize=11,
|
||||
)
|
||||
ax.set_xlabel("Dimension 1")
|
||||
ax.set_ylabel("Dimension 2")
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if not external_axes:
|
||||
theme.visualize_output()
|
||||
|
||||
return top_n_name
|
||||
|
||||
@@ -89,12 +89,14 @@ def display_historical(
|
||||
return
|
||||
(ax,) = external_axes
|
||||
|
||||
ax.plot(df_similar)
|
||||
# breakpoint()
|
||||
companies_names = df_similar.columns.to_list()
|
||||
ax.plot(df_similar, label=companies_names)
|
||||
ax.set_title("Historical price of similar companies")
|
||||
ax.set_ylabel(f"{['','Normalized'][normalize]} Share Price {['($)',''][normalize]}")
|
||||
# ensures that the historical data starts from same datapoint
|
||||
ax.set_xlim([df_similar.index[0], df_similar.index[-1]])
|
||||
|
||||
ax.legend(loc="best")
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if not external_axes:
|
||||
@@ -139,13 +141,15 @@ def display_volume(
|
||||
(ax,) = external_axes
|
||||
|
||||
df_similar = df_similar.div(1_000_000)
|
||||
companies_names = df_similar.columns.to_list()
|
||||
|
||||
ax.plot(df_similar)
|
||||
ax.plot(df_similar, label=companies_names)
|
||||
ax.set_title("Historical volume of similar companies")
|
||||
ax.set_ylabel("Volume [M]")
|
||||
# ensures that the historical data starts from same datapoint
|
||||
ax.set_xlim([df_similar.index[0], df_similar.index[-1]])
|
||||
|
||||
ax.legend()
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if not external_axes:
|
||||
|
||||
@@ -108,6 +108,7 @@ def plot_dark_pools(
|
||||
ax2.set_ylabel("Shares per Trade")
|
||||
ax2.xaxis.set_major_formatter(mdates.DateFormatter("%m/%d"))
|
||||
ax2.xaxis.set_major_locator(mdates.DayLocator(interval=4))
|
||||
ax2.set_xlim(otc.index[0], otc.index[-1])
|
||||
ax2.set_xlabel("Weeks")
|
||||
|
||||
theme.style_primary_axis(ax1)
|
||||
@@ -191,6 +192,8 @@ def plot_dark_pools_ats(
|
||||
ax.set_ylabel("Total Weekly Shares [Million]")
|
||||
ax.set_title("Dark Pool (ATS) growing tickers")
|
||||
ax.set_xlabel("Weeks")
|
||||
ats["weekStartDate"] = pd.to_datetime(ats["weekStartDate"])
|
||||
ax.set_xlim(ats["weekStartDate"].iloc[0], ats["weekStartDate"].iloc[-1])
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if not external_axes:
|
||||
|
||||
@@ -86,6 +86,11 @@ def display_short_by_exchange(
|
||||
# remove the scientific notion on the left hand side
|
||||
ax.ticklabel_format(style="plain", axis="y")
|
||||
|
||||
ax.set_xlim(
|
||||
volume_by_exchange.Date.iloc[0],
|
||||
volume_by_exchange.Date.iloc[-1],
|
||||
)
|
||||
|
||||
ax.set_title(f"Net Short Volume for {ticker}")
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
|
||||
@@ -71,9 +71,11 @@ def fails_to_deliver(
|
||||
ax1.bar(
|
||||
ftds_data["SETTLEMENT DATE"],
|
||||
ftds_data["QUANTITY (FAILS)"] / 1000,
|
||||
label="Fail Quantity",
|
||||
)
|
||||
ax1.set_ylabel("Shares [K]")
|
||||
ax1.set_title(f"Fails-to-deliver Data for {ticker}")
|
||||
ax1.legend(loc="lower right")
|
||||
|
||||
if num > 0:
|
||||
stock_ftd = stock[stock.index > (datetime.now() - timedelta(days=num + 31))]
|
||||
@@ -81,8 +83,11 @@ def fails_to_deliver(
|
||||
stock_ftd = stock[stock.index > start]
|
||||
stock_ftd = stock_ftd[stock_ftd.index < end]
|
||||
|
||||
ax2.plot(stock_ftd.index, stock_ftd["Adj Close"], color="tab:orange")
|
||||
ax2.plot(
|
||||
stock_ftd.index, stock_ftd["Adj Close"], color="orange", label="Share Price"
|
||||
)
|
||||
ax2.set_ylabel("Share Price [$]")
|
||||
ax2.legend(loc="upper right")
|
||||
|
||||
theme.style_twin_axes(ax1, ax2)
|
||||
|
||||
|
||||
@@ -197,7 +197,6 @@ def short_interest_volume(
|
||||
df["total_volume"] / 1_000_000,
|
||||
width=timedelta(days=1),
|
||||
color=theme.up_color,
|
||||
alpha=0.4,
|
||||
label="Total Volume",
|
||||
)
|
||||
ax.bar(
|
||||
@@ -205,7 +204,6 @@ def short_interest_volume(
|
||||
df["short_volume"] / 1_000_000,
|
||||
width=timedelta(days=1),
|
||||
color=theme.down_color,
|
||||
alpha=0.4,
|
||||
label="Short Volume",
|
||||
)
|
||||
|
||||
@@ -327,7 +325,6 @@ def net_short_position(
|
||||
df["dates"],
|
||||
df["dollar_net_volume"] / 1_000,
|
||||
color=theme.down_color,
|
||||
alpha=0.4,
|
||||
label="Net Short Vol. (1k $)",
|
||||
)
|
||||
ax1.set_ylabel("Net Short Vol. (1k $)")
|
||||
|
||||
@@ -85,10 +85,12 @@ def price_target_from_analysts(
|
||||
df_analyst_data = df_analyst_data[start:] # type: ignore
|
||||
|
||||
if interval == "1440min":
|
||||
ax.plot(stock.index, stock["Adj Close"].values, lw=3)
|
||||
ax.plot(stock.index, stock["Adj Close"].values)
|
||||
legend_price_label = "Adjusted closing price"
|
||||
# Intraday
|
||||
else:
|
||||
ax.plot(stock.index, stock["Close"].values, lw=3)
|
||||
ax.plot(stock.index, stock["Close"].values)
|
||||
legend_price_label = "Closing price"
|
||||
|
||||
if start:
|
||||
ax.plot(df_analyst_data.groupby(by=["Date"]).mean()[start:]) # type: ignore
|
||||
@@ -96,10 +98,14 @@ def price_target_from_analysts(
|
||||
ax.plot(df_analyst_data.groupby(by=["Date"]).mean())
|
||||
|
||||
ax.scatter(
|
||||
df_analyst_data.index, df_analyst_data["Price Target"], c="red", s=40
|
||||
df_analyst_data.index,
|
||||
df_analyst_data["Price Target"],
|
||||
color=theme.down_color,
|
||||
edgecolors=theme.up_color,
|
||||
zorder=2,
|
||||
)
|
||||
|
||||
ax.legend(["Closing Price", "Average Price Target", "Price Target"])
|
||||
ax.legend([legend_price_label, "Average Price Target", "Price Target"])
|
||||
|
||||
ax.set_title(f"{ticker} (Time Series) and Price Target")
|
||||
ax.set_xlim(stock.index[0], stock.index[-1])
|
||||
|
||||
@@ -191,11 +191,12 @@ def display_dividends(
|
||||
mfc=theme.down_color,
|
||||
mec=theme.down_color,
|
||||
alpha=1,
|
||||
label="Dividends Payout",
|
||||
)
|
||||
ax.set_ylabel("Amount ($)")
|
||||
ax.set_title(f"Dividend History for {ticker}")
|
||||
ax.set_xlim(div_history.index[-1], div_history.index[0])
|
||||
|
||||
ax.legend()
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if not external_axes:
|
||||
|
||||
@@ -11,6 +11,7 @@ from datetime import datetime, timedelta
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from matplotlib import pyplot as plt
|
||||
import matplotlib
|
||||
|
||||
from gamestonk_terminal.config_terminal import theme
|
||||
from gamestonk_terminal.config_plot import PLOT_DPI
|
||||
@@ -203,9 +204,10 @@ def display_government_buys(
|
||||
return
|
||||
(ax,) = external_axes
|
||||
|
||||
colors = theme.get_colors()
|
||||
df_gov.groupby("Ticker")["upper"].sum().div(1000).sort_values(ascending=False).head(
|
||||
n=num
|
||||
).plot(kind="bar", rot=0, ax=ax)
|
||||
).plot(kind="bar", rot=0, ax=ax, color=colors)
|
||||
|
||||
ax.set_ylabel("Amount [1k $]")
|
||||
ax.set_title(
|
||||
@@ -321,15 +323,15 @@ def display_government_sells(
|
||||
return
|
||||
(ax,) = external_axes
|
||||
|
||||
colors = theme.get_colors()
|
||||
df_gov.groupby("Ticker")["upper"].sum().div(1000).sort_values().abs().head(
|
||||
n=num
|
||||
).plot(kind="bar", rot=0, ax=ax)
|
||||
).plot(kind="bar", rot=0, ax=ax, color=colors)
|
||||
ax.set_ylabel("Amount ($1k)")
|
||||
ax.set_title(
|
||||
f"{num} most sold stocks over last {past_transactions_months} months"
|
||||
f" (upper bound) for {gov_type}"
|
||||
)
|
||||
# plt.gcf().axes[0].yaxis.get_major_formatter().set_scientific(False)
|
||||
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
@@ -608,6 +610,8 @@ def display_contracts(
|
||||
ax.set_ylabel("Amount ($1k)")
|
||||
ax.set_title(f"Sum of latest government contracts to {ticker}")
|
||||
|
||||
ax.xaxis.set_major_locator(matplotlib.ticker.MultipleLocator(4))
|
||||
|
||||
theme.style_primary_axis(ax)
|
||||
|
||||
if not external_axes:
|
||||
@@ -775,7 +779,14 @@ def display_hist_contracts(
|
||||
return
|
||||
(ax,) = external_axes
|
||||
|
||||
ax.plot(np.arange(0, len(amounts)), amounts / 1000, "-*", lw=2, ms=15)
|
||||
ax.plot(
|
||||
np.arange(0, len(amounts)),
|
||||
amounts / 1000,
|
||||
marker=".",
|
||||
markerfacecolor=theme.down_color,
|
||||
lw=2,
|
||||
ms=15,
|
||||
)
|
||||
|
||||
ax.set_xlim([-0.5, len(amounts) - 0.5])
|
||||
ax.set_xticks(np.arange(0, len(amounts)))
|
||||
@@ -844,7 +855,8 @@ def display_top_lobbying(
|
||||
return
|
||||
(ax,) = external_axes
|
||||
|
||||
lobbying_by_ticker.head(num).plot(kind="bar", ax=ax)
|
||||
colors = theme.get_colors()
|
||||
lobbying_by_ticker.head(num).plot(kind="bar", ax=ax, color=colors)
|
||||
ax.set_xlabel("Ticker")
|
||||
ax.set_ylabel("Total Amount ($100k)")
|
||||
ax.set_title(f"Corporate Lobbying Spent since {df_lobbying['Date'].min()}")
|
||||
|
||||
@@ -103,7 +103,7 @@ def insider_activity(
|
||||
* float(row["Shares Traded"].replace(",", "")),
|
||||
axis=1,
|
||||
)
|
||||
ax.set_xlim(df_insider.index[0], stock.index[-1])
|
||||
ax.set_xlim(right=stock.index[-1])
|
||||
min_price, max_price = ax.get_ylim()
|
||||
|
||||
price_range = max_price - min_price
|
||||
|
||||
@@ -296,8 +296,8 @@ def display_companies_per_sector_in_country(
|
||||
df["Number of companies"] = df["Number of companies"].astype(int)
|
||||
|
||||
title = mktcap + " cap companies " if mktcap else "Companies "
|
||||
title += f"in {country}"
|
||||
title += " excl. exchanges" if exclude_exchanges else " incl. exchanges"
|
||||
title += f"in {country}\n"
|
||||
title += "excl. exchanges" if exclude_exchanges else " incl. exchanges"
|
||||
|
||||
if raw:
|
||||
print_rich_table(df, headers=list(df.columns), show_index=True, title=title)
|
||||
@@ -357,7 +357,7 @@ def display_companies_per_sector_in_country(
|
||||
colors=colors,
|
||||
wedgeprops={"linewidth": 0.5, "edgecolor": "white"},
|
||||
labeldistance=1.05,
|
||||
startangle=90,
|
||||
startangle=45,
|
||||
)
|
||||
ax.set_title(title, fontsize=14)
|
||||
|
||||
@@ -439,8 +439,8 @@ def display_companies_per_industry_in_country(
|
||||
df["Number of companies"] = df["Number of companies"].astype(int)
|
||||
|
||||
title = mktcap + " cap companies " if mktcap else "Companies "
|
||||
title += f"in {country}"
|
||||
title += " excl. exchanges" if exclude_exchanges else " incl. exchanges"
|
||||
title += f"in {country}\n"
|
||||
title += "excl. exchanges" if exclude_exchanges else " incl. exchanges"
|
||||
|
||||
if raw:
|
||||
print_rich_table(df, headers=list(df.columns), show_index=True, title=title)
|
||||
@@ -507,7 +507,7 @@ def display_companies_per_industry_in_country(
|
||||
colors=colors,
|
||||
wedgeprops={"linewidth": 0.5, "edgecolor": "white"},
|
||||
labeldistance=1.05,
|
||||
startangle=90,
|
||||
startangle=45,
|
||||
)
|
||||
|
||||
ax.set_title(title, fontsize=14)
|
||||
@@ -587,8 +587,8 @@ def display_companies_per_industry_in_sector(
|
||||
df["Number of companies"] = df["Number of companies"].astype(int)
|
||||
|
||||
title = mktcap + " cap companies " if mktcap else "Companies "
|
||||
title += f"in {sector} sector"
|
||||
title += " excl. exchanges" if exclude_exchanges else " incl. exchanges"
|
||||
title += f"in {sector} sector\n"
|
||||
title += "excl. exchanges" if exclude_exchanges else " incl. exchanges"
|
||||
|
||||
if raw:
|
||||
print_rich_table(
|
||||
@@ -660,7 +660,7 @@ def display_companies_per_industry_in_sector(
|
||||
colors=colors,
|
||||
wedgeprops={"linewidth": 0.5, "edgecolor": "white"},
|
||||
labeldistance=1.05,
|
||||
startangle=90,
|
||||
startangle=45,
|
||||
)
|
||||
ax.set_title(title, fontsize=14)
|
||||
|
||||
@@ -739,8 +739,8 @@ def display_companies_per_country_in_sector(
|
||||
df["Number of companies"] = df["Number of companies"].astype(int)
|
||||
|
||||
title = mktcap + " cap companies " if mktcap else "Companies "
|
||||
title += f"in {sector} sector"
|
||||
title += " excl. exchanges" if exclude_exchanges else " incl. exchanges"
|
||||
title += f"in {sector} sector\n"
|
||||
title += "excl. exchanges" if exclude_exchanges else " incl. exchanges"
|
||||
|
||||
if raw:
|
||||
print_rich_table(df, headers=list(df.columns), show_index=True, title=title)
|
||||
@@ -805,7 +805,7 @@ def display_companies_per_country_in_sector(
|
||||
colors=colors,
|
||||
wedgeprops={"linewidth": 0.5, "edgecolor": "white"},
|
||||
labeldistance=1.05,
|
||||
startangle=90,
|
||||
startangle=45,
|
||||
)
|
||||
ax.set_title(title, fontsize=14)
|
||||
|
||||
@@ -884,8 +884,8 @@ def display_companies_per_country_in_industry(
|
||||
df["Number of companies"] = df["Number of companies"].astype(int)
|
||||
|
||||
title = mktcap + " cap companies " if mktcap else "Companies "
|
||||
title += f"per country in {industry} industry"
|
||||
title += " excl. exchanges" if exclude_exchanges else " incl. exchanges"
|
||||
title += f"per country in {industry} industry\n"
|
||||
title += "excl. exchanges" if exclude_exchanges else " incl. exchanges"
|
||||
|
||||
if raw:
|
||||
print_rich_table(df, headers=list(df.columns), show_index=True, title=title)
|
||||
@@ -950,7 +950,7 @@ def display_companies_per_country_in_industry(
|
||||
colors=colors,
|
||||
wedgeprops={"linewidth": 0.5, "edgecolor": "white"},
|
||||
labeldistance=1.05,
|
||||
startangle=90,
|
||||
startangle=45,
|
||||
)
|
||||
ax.set_title(title, fontsize=14)
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ from numpy.core.fromnumeric import transpose
|
||||
from plotly.subplots import make_subplots
|
||||
from scipy import stats
|
||||
|
||||
from gamestonk_terminal.config_terminal import theme
|
||||
from gamestonk_terminal import config_terminal as cfg
|
||||
from gamestonk_terminal import feature_flags as gtff
|
||||
from gamestonk_terminal.helper_funcs import (
|
||||
parse_known_args_and_warn,
|
||||
plot_autoscale,
|
||||
@@ -269,6 +269,7 @@ def display_candle(
|
||||
add_trend: bool = False,
|
||||
ma: Optional[Tuple[int, ...]] = None,
|
||||
asset_type: str = "Stock",
|
||||
external_axes: Optional[List[plt.Axes]] = None,
|
||||
):
|
||||
"""Shows candle plot of loaded ticker. [Source: Yahoo Finance, IEX Cloud or Alpha Vantage]
|
||||
|
||||
@@ -288,6 +289,10 @@ def display_candle(
|
||||
Moving averages to add to the candle
|
||||
asset_type_: str
|
||||
String to include in title
|
||||
external_axes : Optional[List[plt.Axes]], optional
|
||||
External axes (2 axes are expected in the list), by default None
|
||||
asset_type_: str
|
||||
String to include in title
|
||||
"""
|
||||
if add_trend:
|
||||
if (df_stock.index[1] - df_stock.index[0]).total_seconds() >= 86400:
|
||||
@@ -299,45 +304,54 @@ def display_candle(
|
||||
if add_trend:
|
||||
if "OC_High_trend" in df_stock.columns:
|
||||
ap0.append(
|
||||
mpf.make_addplot(df_stock["OC_High_trend"], color="g"),
|
||||
mpf.make_addplot(df_stock["OC_High_trend"], color=theme.up_color),
|
||||
)
|
||||
|
||||
if "OC_Low_trend" in df_stock.columns:
|
||||
ap0.append(
|
||||
mpf.make_addplot(df_stock["OC_Low_trend"], color="b"),
|
||||
mpf.make_addplot(df_stock["OC_Low_trend"], color=theme.down_color),
|
||||
)
|
||||
|
||||
if gtff.USE_ION:
|
||||
plt.ion()
|
||||
candle_chart_kwargs = {
|
||||
"type": "candle",
|
||||
"style": theme.mpf_style,
|
||||
"volume": True,
|
||||
"addplot": ap0,
|
||||
"xrotation": theme.xticks_rotation,
|
||||
"scale_padding": {"left": 0.3, "right": 1, "top": 0.8, "bottom": 0.8},
|
||||
"update_width_config": {
|
||||
"candle_linewidth": 0.6,
|
||||
"candle_width": 0.8,
|
||||
"volume_linewidth": 0.8,
|
||||
"volume_width": 0.8,
|
||||
},
|
||||
"warn_too_much_data": 10000,
|
||||
}
|
||||
|
||||
kwargs = {"mav": ma} if ma else {}
|
||||
|
||||
fig, _ = mpf.plot(
|
||||
df_stock,
|
||||
type="candle",
|
||||
style=cfg.theme.mpf_style,
|
||||
volume=True,
|
||||
addplot=ap0,
|
||||
xrotation=10,
|
||||
figratio=(10, 7),
|
||||
figscale=1.10,
|
||||
scale_padding={"left": 0.3, "right": 1.1, "top": 0.8, "bottom": 0.8},
|
||||
figsize=(plot_autoscale()),
|
||||
update_width_config=dict(
|
||||
candle_linewidth=0.6,
|
||||
candle_width=0.8,
|
||||
volume_linewidth=0.8,
|
||||
volume_width=0.8,
|
||||
),
|
||||
warn_too_much_data=10000,
|
||||
returnfig=True,
|
||||
**kwargs,
|
||||
)
|
||||
fig.suptitle(
|
||||
f"{asset_type} {s_ticker}",
|
||||
x=0.055,
|
||||
y=0.965,
|
||||
horizontalalignment="left",
|
||||
)
|
||||
if external_axes is None:
|
||||
candle_chart_kwargs["returnfig"] = True
|
||||
candle_chart_kwargs["figratio"] = (10, 7)
|
||||
candle_chart_kwargs["figscale"] = 1.10
|
||||
candle_chart_kwargs["figsize"] = plot_autoscale()
|
||||
fig, _ = mpf.plot(df_stock, **candle_chart_kwargs, **kwargs)
|
||||
fig.suptitle(
|
||||
f"{asset_type} {s_ticker}",
|
||||
x=0.055,
|
||||
y=0.965,
|
||||
horizontalalignment="left",
|
||||
)
|
||||
|
||||
theme.visualize_output(force_tight_layout=False)
|
||||
else:
|
||||
if len(external_axes) != 1:
|
||||
console.print("[red]Expected list of 1 axis items./n[/red]")
|
||||
return
|
||||
(ax1,) = external_axes
|
||||
candle_chart_kwargs["ax"] = ax1
|
||||
mpf.plot(df_stock, **candle_chart_kwargs)
|
||||
|
||||
else:
|
||||
fig = make_subplots(
|
||||
rows=2,
|
||||
|
||||
2
styles/default/dark.mplstyle
vendored
2
styles/default/dark.mplstyle
vendored
@@ -54,6 +54,7 @@ xtick.major.size: 2
|
||||
xtick.minor.size: 1
|
||||
xtick.labelsize: small
|
||||
xtick.alignment: center
|
||||
xtick.major.width: 0.2
|
||||
|
||||
ytick.major.size: 2
|
||||
ytick.minor.size: 1
|
||||
@@ -63,6 +64,7 @@ ytick.left: False
|
||||
ytick.labelleft: False
|
||||
ytick.right: True
|
||||
ytick.labelright: True
|
||||
ytick.major.width: 0.2
|
||||
|
||||
grid.color: F5EFF3
|
||||
grid.linewidth: 0.4
|
||||
|
||||
@@ -6,6 +6,7 @@ import pytest
|
||||
|
||||
# IMPORTATION INTERNAL
|
||||
from gamestonk_terminal.stocks import stocks_helper
|
||||
from gamestonk_terminal import helper_funcs
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
@@ -35,7 +36,7 @@ def test_quote():
|
||||
)
|
||||
def test_search(mocker, use_tab):
|
||||
mocker.patch.object(
|
||||
target=stocks_helper.gtff, attribute="USE_TABULATE_DF", new=use_tab
|
||||
target=helper_funcs.gtff, attribute="USE_TABULATE_DF", new=use_tab
|
||||
)
|
||||
stocks_helper.search(query="pharma", amount=5)
|
||||
|
||||
@@ -73,8 +74,11 @@ def test_load(interval, recorder, source):
|
||||
[True, False],
|
||||
)
|
||||
def test_display_candle(mocker, use_matplotlib):
|
||||
mocker.patch.object(target=stocks_helper.gtff, attribute="USE_ION", new=False)
|
||||
mocker.patch("matplotlib.pyplot.show")
|
||||
# MOCK VISUALIZE_OUTPUT
|
||||
mocker.patch(
|
||||
target="gamestonk_terminal.helper_classes.TerminalStyle.visualize_output"
|
||||
)
|
||||
|
||||
mocker.patch("plotly.basedatatypes.BaseFigure.show")
|
||||
|
||||
# LOAD DATA
|
||||
|
||||
Reference in New Issue
Block a user