Fix projection plot bugs.

This commit is contained in:
sam
2024-11-16 21:46:31 -08:00
parent 06f5620cb3
commit 56f669ac0f
+36 -9
View File
@@ -646,14 +646,20 @@ def create_plots(df, start=None, end=None, project_days=365):
# Set up the style
plt.style.use("seaborn-v0_8")
# Create figure with adjusted size for additional subplot
_ = plt.figure(figsize=(15, 15)) # Increased height to accommodate new subplot
# Create figure with adjusted size and spacing
fig = plt.figure(figsize=(15, 15))
# Use GridSpec for better control over subplot spacing
gs = plt.GridSpec(5, 1, height_ratios=[3, 1.5, 1.5, 1.5, 2], hspace=0.4)
# Date range for titles
hist_date_range = f" ({plot_df['Date'].min().strftime('%Y-%m-%d')} to {plot_df['Date'].max().strftime('%Y-%m-%d')})"
# Calculate full date range including projections
full_date_range = pd.date_range(plot_df["Date"].min(), projections.index.max())
# 1. Price history and projections (log scale)
ax1 = plt.subplot(4, 1, 1)
ax1 = fig.add_subplot(gs[0])
# Plot historical prices
ax1.semilogy(plot_df["Date"], plot_df["Close"], "b-", label="Historical Price")
@@ -703,22 +709,43 @@ def create_plots(df, start=None, end=None, project_days=365):
ax1.set_title("Bitcoin Price History and Projections (Log Scale)" + hist_date_range)
ax1.legend(fontsize=8)
# Set x-axis limits to full range
ax1.set_xlim(full_date_range[0], full_date_range[-1])
ax1.tick_params(axis="x", rotation=45)
# 3. Rolling volatility
ax3 = plt.subplot(5, 1, 2)
ax3 = fig.add_subplot(gs[1])
ax3.plot(
plot_df["Date"],
plot_df["Rolling_Volatility_30d"],
"r-",
label="30-Day Rolling Volatility",
)
# Add empty space to match price plot x-axis
ax3.set_xlim(full_date_range[0], full_date_range[-1])
# Add vertical line to mark start of projections
ax3.axvline(plot_df["Date"].max(), color="gray", linestyle="--", alpha=0.5)
ax3.text(
plot_df["Date"].max(),
ax3.get_ylim()[1],
"Projection Start",
rotation=90,
va="top",
ha="right",
alpha=0.7,
)
ax3.set_title("30-Day Rolling Volatility (Annualized)" + hist_date_range)
ax3.set_ylabel("Volatility")
ax3.grid(True)
ax3.yaxis.set_major_formatter(plt.FuncFormatter(lambda y, _: "{:.0%}".format(y)))
ax3.legend()
ax3.tick_params(axis="x", rotation=45)
# 4. Returns distribution
ax4 = plt.subplot(5, 1, 3)
ax4 = fig.add_subplot(gs[2])
returns_mean = plot_df["Daily_Return"].mean()
returns_std = plot_df["Daily_Return"].std()
filtered_returns = plot_df["Daily_Return"][
@@ -746,7 +773,7 @@ def create_plots(df, start=None, end=None, project_days=365):
)
# 5. Projection ranges
ax5 = plt.subplot(5, 1, 4)
ax5 = fig.add_subplot(gs[3:]) # Use last two grid spaces for larger plot
timepoints = np.array(range(30, project_days, 30))
timepoints = timepoints[timepoints <= project_days]
@@ -786,13 +813,13 @@ def create_plots(df, start=None, end=None, project_days=365):
ax5.grid(True, alpha=0.3)
ax5.set_xticks(timepoints)
# Adjust layout
plt.tight_layout(h_pad=1.0) # Increased spacing between subplots
# Save the plot
start_str = start if start else plot_df["Date"].min().strftime("%Y-%m-%d")
end_str = end if end else plot_df["Date"].max().strftime("%Y-%m-%d")
filename = f"bitcoin_analysis_{start_str}_to_{end_str}_with_projections.png"
# Use tight_layout with adjusted parameters
plt.tight_layout(pad=2.0)
plt.savefig(filename, dpi=300, bbox_inches="tight")
plt.close()