解决Matplotlib绘制SBIN NSE均线时非交易时段绘图问题
Got it, let's tackle this problem: your chart is showing the gap between 15:30 (end of one trading day) and 9:15 (start of the next) because Matplotlib treats datetime axes as continuous physical time. Even though your DataFrame only has trading hours data, the plot still accounts for the real-world time gap between sessions. Here's how to make the trading periods connect seamlessly:
Step 1: Prepare Your Data (Double-Check)
First, ensure your timestamp column is properly parsed as datetime and set as the index. If you haven't already, do this:
import pandas as pd import matplotlib.pyplot as plt # Load your CSV data df = pd.read_csv('your_data.csv', parse_dates=['timestamp'], index_col='timestamp') # Filter to keep only 9:15-15:30 data (confirm your existing filter works) trading_mask = df.index.indexer_between_time('09:15', '15:30') df = df.iloc[trading_mask]
Step 2: Plot Using Integer Index (Skip Time Gaps)
The trick is to plot against a sequential integer index instead of the raw datetime index. This tells Matplotlib to draw points in order without accounting for the real-time gaps between trading days. Then we'll re-label the x-axis with meaningful trading session times.
# Create a sequential integer x-axis (one value per data point) x = range(len(df)) # Initialize plot plt.figure(figsize=(12, 6)) # Plot your moving averages plt.plot(x, df['MA_50'], label='MA_50', linewidth=1.5) plt.plot(x, df['MA_10'], label='MA_10', linewidth=1.5) # Customize x-axis to show only daily session starts (avoid clutter) # Get the first timestamp of each trading day daily_start_timestamps = df.index.groupby(df.index.date).first() # Map these timestamps to their positions in the integer x-axis x_tick_positions = [df.index.get_loc(ts) for ts in daily_start_timestamps] # Format labels to show date + opening time x_tick_labels = [ts.strftime('%Y-%m-%d %H:%M') for ts in daily_start_timestamps] # Set x-ticks and rotate for readability plt.xticks(x_tick_positions, x_tick_labels, rotation=45, ha='right') # Add labels and legend plt.xlabel('Trading Session') plt.ylabel('Price') plt.title('MA_50 & MA_10 (Continuous Trading Periods)') plt.legend() # Adjust layout to prevent label cutoff plt.tight_layout() plt.show()
Why This Works
When you use the integer index, Matplotlib plots each data point one after another, ignoring the actual time gap between the end of one day and the start of the next. The custom x-ticks still let you see which trading day each segment corresponds to, without the annoying blank space in the chart.
Bonus: If You Want Interactive Tooltips
If you want to hover over points and see the exact timestamp, you can use mplcursors (install with pip install mplcursors):
import mplcursors # After plotting your lines cursor = mplcursors.cursor(hover=True) @cursor.connect("add") def on_add(sel): # Get the index of the selected point idx = sel.target.index # Get the original datetime from the DataFrame timestamp = df.index[idx] # Show timestamp and values in tooltip sel.annotation.set_text(f"{timestamp.strftime('%Y-%m-%d %H:%M')}\nMA_50: {df['MA_50'].iloc[idx]:.2f}\nMA_10: {df['MA_10'].iloc[idx]:.2f}")
内容的提问来源于stack exchange,提问作者Ranit

