# Matplotlib Common Issues and Solutions Troubleshooting guide for frequently encountered matplotlib problems. ## Display and Backend Issues ### Issue: Plots Not Showing **Problem:** `plt.show()` doesn't display anything **Solutions:** ```python # 1. Check if backend is properly set (for interactive use) import matplotlib print(matplotlib.get_backend()) # 2. Try different backends matplotlib.use('TkAgg') # or 'Qt5Agg', 'MacOSX' import matplotlib.pyplot as plt # 3. In Jupyter notebooks, use magic command %matplotlib inline # Static images # or %matplotlib widget # Interactive plots # 4. Ensure plt.show() is called plt.plot([1, 2, 3]) plt.show() ``` ### Issue: "RuntimeError: main thread is not in main loop" **Problem:** Interactive mode issues with threading **Solution:** ```python # Switch to non-interactive backend import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt # Or turn off interactive mode plt.ioff() ``` ### Issue: Figures Not Updating Interactively **Problem:** Changes not reflected in interactive windows **Solution:** ```python # Enable interactive mode plt.ion() # Draw after each change plt.plot(x, y) plt.draw() plt.pause(0.001) # Brief pause to update display ``` ## Layout and Spacing Issues ### Issue: Overlapping Labels and Titles **Problem:** Labels, titles, or tick labels overlap or get cut off **Solutions:** ```python # Solution 1: Constrained layout (RECOMMENDED) fig, ax = plt.subplots(constrained_layout=True) # Solution 2: Tight layout fig, ax = plt.subplots() plt.tight_layout() # Solution 3: Adjust margins manually plt.subplots_adjust(left=0.15, right=0.95, top=0.95, bottom=0.15) # Solution 4: Save with bbox_inches='tight' plt.savefig('figure.png', bbox_inches='tight') # Solution 5: Rotate long tick labels ax.set_xticklabels(labels, rotation=45, ha='right') ``` ### Issue: Colorbar Affects Subplot Size **Problem:** Adding colorbar shrinks the plot **Solution:** ```python # Solution 1: Use constrained layout fig, ax = plt.subplots(constrained_layout=True) im = ax.imshow(data) plt.colorbar(im, ax=ax) # Solution 2: Manually specify colorbar dimensions from mpl_toolkits.axes_grid1 import make_axes_locatable divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) plt.colorbar(im, cax=cax) # Solution 3: For multiple subplots, share colorbar fig, axes = plt.subplots(1, 3, figsize=(15, 4)) for ax in axes: im = ax.imshow(data) fig.colorbar(im, ax=axes.ravel().tolist(), shrink=0.95) ``` ### Issue: Subplots Too Close Together **Problem:** Multiple subplots overlapping **Solution:** ```python # Solution 1: Use constrained_layout fig, axes = plt.subplots(2, 2, constrained_layout=True) # Solution 2: Adjust spacing with subplots_adjust fig, axes = plt.subplots(2, 2) plt.subplots_adjust(hspace=0.4, wspace=0.4) # Solution 3: Specify spacing in tight_layout plt.tight_layout(h_pad=2.0, w_pad=2.0) ``` ## Memory and Performance Issues ### Issue: Memory Leak with Multiple Figures **Problem:** Memory usage grows when creating many figures **Solution:** ```python # Close figures explicitly fig, ax = plt.subplots() ax.plot(x, y) plt.savefig('plot.png') plt.close(fig) # or plt.close('all') # Clear current figure without closing plt.clf() # Clear current axes plt.cla() ``` ### Issue: Large File Sizes **Problem:** Saved figures are too large **Solutions:** ```python # Solution 1: Reduce DPI plt.savefig('figure.png', dpi=150) # Instead of 300 # Solution 2: Use rasterization for complex plots ax.plot(x, y, rasterized=True) # Solution 3: Use vector format for simple plots plt.savefig('figure.pdf') # or .svg # Solution 4: Compress PNG plt.savefig('figure.png', dpi=300, optimize=True) ``` ### Issue: Slow Plotting with Large Datasets **Problem:** Plotting takes too long with many points **Solutions:** ```python # Solution 1: Downsample data from scipy.signal import decimate y_downsampled = decimate(y, 10) # Keep every 10th point # Solution 2: Use rasterization ax.plot(x, y, rasterized=True) # Solution 3: Use line simplification ax.plot(x, y) for line in ax.get_lines(): line.set_rasterized(True) # Solution 4: For scatter plots, consider hexbin or 2d histogram ax.hexbin(x, y, gridsize=50, cmap='viridis') ``` ## Font and Text Issues ### Issue: Font Warnings **Problem:** "findfont: Font family [...] not found" **Solutions:** ```python # Solution 1: Use available fonts from matplotlib.font_manager import findfont, FontProperties print(findfont(FontProperties(family='sans-serif'))) # Solution 2: Rebuild font cache import matplotlib.font_manager matplotlib.font_manager._rebuild() # Solution 3: Suppress warnings import warnings warnings.filterwarnings("ignore", category=UserWarning) # Solution 4: Specify fallback fonts plt.rcParams['font.sans-serif'] = ['Arial', 'DejaVu Sans', 'sans-serif'] ``` ### Issue: LaTeX Rendering Errors **Problem:** Math text not rendering correctly **Solutions:** ```python # Solution 1: Use raw strings with r prefix ax.set_xlabel(r'$\alpha$') # Not '\alpha' # Solution 2: Escape backslashes in regular strings ax.set_xlabel('$\\alpha$') # Solution 3: Disable LaTeX if not installed plt.rcParams['text.usetex'] = False # Solution 4: Use mathtext instead of full LaTeX # Mathtext is always available, no LaTeX installation needed ax.text(x, y, r'$\int_0^\infty e^{-x} dx$') ``` ### Issue: Text Cut Off or Outside Figure **Problem:** Labels or annotations appear outside figure bounds **Solutions:** ```python # Solution 1: Use bbox_inches='tight' plt.savefig('figure.png', bbox_inches='tight') # Solution 2: Adjust figure bounds plt.subplots_adjust(left=0.15, right=0.85, top=0.85, bottom=0.15) # Solution 3: Clip text to axes ax.text(x, y, 'text', clip_on=True) # Solution 4: Use constrained_layout fig, ax = plt.subplots(constrained_layout=True) ``` ## Color and Colormap Issues ### Issue: Colorbar Not Matching Plot **Problem:** Colorbar shows different range than data **Solution:** ```python # Explicitly set vmin and vmax im = ax.imshow(data, vmin=0, vmax=1, cmap='viridis') plt.colorbar(im, ax=ax) # Or use the same norm for multiple plots import matplotlib.colors as mcolors norm = mcolors.Normalize(vmin=data.min(), vmax=data.max()) im1 = ax1.imshow(data1, norm=norm, cmap='viridis') im2 = ax2.imshow(data2, norm=norm, cmap='viridis') ``` ### Issue: Colors Look Wrong **Problem:** Unexpected colors in plots **Solutions:** ```python # Solution 1: Check color specification format ax.plot(x, y, color='blue') # Correct ax.plot(x, y, color=(0, 0, 1)) # Correct RGB ax.plot(x, y, color='#0000FF') # Correct hex # Solution 2: Verify colormap exists print(plt.colormaps()) # List available colormaps # Solution 3: For scatter plots, ensure c shape matches ax.scatter(x, y, c=colors) # colors should have same length as x, y # Solution 4: Check if alpha is set correctly ax.plot(x, y, alpha=1.0) # 0=transparent, 1=opaque ``` ### Issue: Reversed Colormap **Problem:** Colormap direction is backwards **Solution:** ```python # Add _r suffix to reverse any colormap ax.imshow(data, cmap='viridis_r') ``` ## Axis and Scale Issues ### Issue: Axis Limits Not Working **Problem:** `set_xlim` or `set_ylim` not taking effect **Solutions:** ```python # Solution 1: Set after plotting ax.plot(x, y) ax.set_xlim(0, 10) ax.set_ylim(-1, 1) # Solution 2: Disable autoscaling ax.autoscale(False) ax.set_xlim(0, 10) # Solution 3: Use axis method ax.axis([xmin, xmax, ymin, ymax]) ``` ### Issue: Log Scale with Zero or Negative Values **Problem:** ValueError when using log scale with data ≤ 0 **Solutions:** ```python # Solution 1: Filter out non-positive values mask = (data > 0) ax.plot(x[mask], data[mask]) ax.set_yscale('log') # Solution 2: Use symlog for data with positive and negative values ax.set_yscale('symlog') # Solution 3: Add small offset ax.plot(x, data + 1e-10) ax.set_yscale('log') ``` ### Issue: Dates Not Displaying Correctly **Problem:** Date axis shows numbers instead of dates **Solution:** ```python import matplotlib.dates as mdates import pandas as pd # Convert to datetime if needed dates = pd.to_datetime(date_strings) ax.plot(dates, values) # Format date axis ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) ax.xaxis.set_major_locator(mdates.DayLocator(interval=7)) plt.xticks(rotation=45) ``` ## Legend Issues ### Issue: Legend Covers Data **Problem:** Legend obscures important parts of plot **Solutions:** ```python # Solution 1: Use 'best' location ax.legend(loc='best') # Solution 2: Place outside plot area ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left') # Solution 3: Make legend semi-transparent ax.legend(framealpha=0.7) # Solution 4: Put legend below plot ax.legend(bbox_to_anchor=(0.5, -0.15), loc='upper center', ncol=3) ``` ### Issue: Too Many Items in Legend **Problem:** Legend is cluttered with many entries **Solutions:** ```python # Solution 1: Only label selected items for i, (x, y) in enumerate(data): label = f'Data {i}' if i % 5 == 0 else None ax.plot(x, y, label=label) # Solution 2: Use multiple columns ax.legend(ncol=3) # Solution 3: Create custom legend with fewer entries from matplotlib.lines import Line2D custom_lines = [Line2D([0], [0], color='r'), Line2D([0], [0], color='b')] ax.legend(custom_lines, ['Category A', 'Category B']) # Solution 4: Use separate legend figure fig_leg = plt.figure(figsize=(3, 2)) ax_leg = fig_leg.add_subplot(111) ax_leg.legend(*ax.get_legend_handles_labels(), loc='center') ax_leg.axis('off') ``` ## 3D Plot Issues ### Issue: 3D Plots Look Flat **Problem:** Difficult to perceive depth in 3D plots **Solutions:** ```python # Solution 1: Adjust viewing angle ax.view_init(elev=30, azim=45) # Solution 2: Add gridlines ax.grid(True) # Solution 3: Use color for depth scatter = ax.scatter(x, y, z, c=z, cmap='viridis') # Solution 4: Rotate interactively (if using interactive backend) # User can click and drag to rotate ``` ### Issue: 3D Axis Labels Cut Off **Problem:** 3D axis labels appear outside figure **Solution:** ```python from mpl_toolkits.mplot3d import Axes3D fig = plt.figure(figsize=(10, 8)) ax = fig.add_subplot(111, projection='3d') ax.plot_surface(X, Y, Z) # Add padding fig.tight_layout(pad=3.0) # Or save with tight bounding box plt.savefig('3d_plot.png', bbox_inches='tight', pad_inches=0.5) ``` ## Image and Colorbar Issues ### Issue: Images Appear Flipped **Problem:** Image orientation is wrong **Solution:** ```python # Set origin parameter ax.imshow(img, origin='lower') # or 'upper' (default) # Or flip array ax.imshow(np.flipud(img)) ``` ### Issue: Images Look Pixelated **Problem:** Image appears blocky when zoomed **Solutions:** ```python # Solution 1: Use interpolation ax.imshow(img, interpolation='bilinear') # Options: 'nearest', 'bilinear', 'bicubic', 'spline16', 'spline36', etc. # Solution 2: Increase DPI when saving plt.savefig('figure.png', dpi=300) # Solution 3: Use vector format if appropriate plt.savefig('figure.pdf') ``` ## Common Errors and Fixes ### "TypeError: 'AxesSubplot' object is not subscriptable" **Problem:** Trying to index single axes ```python # Wrong fig, ax = plt.subplots() ax[0].plot(x, y) # Error! # Correct fig, ax = plt.subplots() ax.plot(x, y) ``` ### "ValueError: x and y must have same first dimension" **Problem:** Data arrays have mismatched lengths ```python # Check shapes print(f"x shape: {x.shape}, y shape: {y.shape}") # Ensure they match assert len(x) == len(y), "x and y must have same length" ``` ### "AttributeError: 'numpy.ndarray' object has no attribute 'plot'" **Problem:** Calling plot on array instead of axes ```python # Wrong data.plot(x, y) # Correct ax.plot(x, y) # or for pandas data.plot(ax=ax) ``` ## Best Practices to Avoid Issues 1. **Always use the OO interface** - Avoid pyplot state machine ```python fig, ax = plt.subplots() # Good ax.plot(x, y) ``` 2. **Use constrained_layout** - Prevents overlap issues ```python fig, ax = plt.subplots(constrained_layout=True) ``` 3. **Close figures explicitly** - Prevents memory leaks ```python plt.close(fig) ``` 4. **Set figure size at creation** - Better than resizing later ```python fig, ax = plt.subplots(figsize=(10, 6)) ``` 5. **Use raw strings for math text** - Avoids escape issues ```python ax.set_xlabel(r'$\alpha$') ``` 6. **Check data shapes before plotting** - Catch size mismatches early ```python assert len(x) == len(y) ``` 7. **Use appropriate DPI** - 300 for print, 150 for web ```python plt.savefig('figure.png', dpi=300) ``` 8. **Test with different backends** - If display issues occur ```python import matplotlib matplotlib.use('TkAgg') ```