当我通过axes.plot(x_data, y_data, label='Close Price', color='r')绘制图表时,我的程序绘制图表。但是,当我通过 mpf.plot 绘制图形时,我的程序无法绘制图形。我无法收到任何错误消息。只是不画。我的代码如下
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.axes import Axes
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
self.fig = plt.figure()
self.canvas = FigureCanvas(self.fig)
self.d_axes_mgr = DynamicSubplotManager(self.fig) ==> axes management class
try:
required_columns = ['Open', 'High', 'Low', 'Close', 'Volume']
for col in required_columns:
if col not in filtered_df.columns:
raise ValueError(f"Missing required column: {col}")
if axes:
print(f"Axes title: {axes.get_title()}")
print(f"Axes xlabel: {axes.get_xlabel()}")
print(f"Axes ylabel: {axes.get_ylabel()}")
mpf.plot(filtered_df[-100:], type='ohlc', ax=ax, style='charles', returnfig=True, warn_too_much_data=len(filtered_df))
# Directly plotting the Close price with a label
#axes.plot(x_data, y_data, label='Close Price', color='r')
#print("Line plot completed successfully")
except ValueError as ve:
print(f"ValueError: {ve}")
except TypeError as te:
print(f"TypeError: {te}")
except KeyError as ke:
print(f"KeyError: {ke}")
ex cept Exception as e:
print(f"Unexpected error: {e}")
self.canvas.draw_idle()```
could you help me?
debugging : axes properties below:
Axes properties: {'_stale': True, 'stale_callback': <function _stale_figure_callback at 0x0000021CC265E7A0>, '_axes': <Axes: >, 'figure': <Figure size 640x480 with 1 Axes>, '_transform': None, '_transformSet': False, '_visible': True, '_animated': False, '_alpha': None, 'clipbox': None, '_clippath': None, '_clipon': True, '_label': '', '_picker': None, '_rasterized': False, '_agg_filter': None, '_mouseover': False, '_callbacks': <matplotlib.cbook.CallbackRegistry object at 0x0000021CCFD581A0>, '_remove_method': <bound method FigureBase.delaxes of <Figure size 640x480 with 1 Axes>>, '_url': None, '_gid': None, '_snap': None, '_sketch': None, '_path_effects': [], '_sticky_edges': _XYPair(x=[], y=[]), '_in_layout': True, '_position': Bbox([[0.0, 0.050000000000000044], [0.92, 1.0]]), '_originalPosition': Bbox([[0.0, 0.050000000000000044], [0.92, 1.0]]), '_aspect': 'auto', '_adjustable': 'box', '_anchor': 'C', '_stale_viewlims': {'x': False, 'y': False}, '_forward_navigation_events': 'auto', '_sharex': None, '_sharey': None, 'bbox': <matplotlib.transforms.TransformedBbox object at 0x0000021CCD603D40>, 'dataLim': Bbox([[inf, inf], [-inf, -inf]]), '_viewLim': Bbox([[18927.375, 15781.29], [19926.375, 73072.41]]), 'transScale': <matplotlib.transforms.TransformWrapper object at 0x0000021CCF8A0B30>, 'transAxes': <matplotlib.transforms.BboxTransformTo object at 0x0000021CCFD5A150>, 'transLimits': <matplotlib.transforms.BboxTransformFrom object at 0x0000021CCF8A39B0>, 'transData': <matplotlib.transforms.CompositeGenericTransform object at 0x0000021CCF8A3290>, '_xaxis_transform': <matplotlib.transforms.BlendedGenericTransform object at 0x0000021CCF8A28D0>, '_yaxis_transform': <matplotlib.transforms.BlendedGenericTransform object at 0x0000021CCF8A0B90>, '_subplotspec': GridSpec(1, 1)[0:1, 0:1], '_box_aspect': None, '_axes_locator': None, '_children': [], '_colorbars': [], 'spines': <matplotlib.spines.Spines object at 0x0000021CCFD5AA20>, 'xaxis': <matplotlib.axis.XAxis object at 0x0000021CCF8A23F0>, 'yaxis': <matplotlib.axis.YAxis object at 0x0000021CCF8A3AA0>, '_facecolor': 'white', '_frameon': True, '_axisbelow': 'line', '_rasterization_zorder': None, 'ignore_existing_data_limits': True, 'callbacks': <matplotlib.cbook.CallbackRegistry object at 0x0000021CCD601BE0>, '_xmargin': 0.05, '_ymargin': 0.05, '_tight': None, '_use_sticky_edges': True, '_get_lines': <matplotlib.axes._base._process_plot_var_args object at 0x0000021CCF8A3B60>, '_get_patches_for_fill': <matplotlib.axes._base._process_plot_var_args object at 0x0000021CCF8A3740>, '_gridOn': False, '_mouseover_set': <matplotlib.cbook._OrderedSet object at 0x0000021CCF8A1850>, 'child_axes': [], '_current_image': None, '_projection_init': (<class 'matplotlib.axes._axes.Axes'>, {}), 'legend_': None, 'containers': [], '_autotitlepos': True, 'title': Text(0.5, 1.0, ''), '_left_title': Text(0.0, 1.0, ''), '_right_title': Text(1.0, 1.0, ''), 'titleOffsetTrans': <matplotlib.transforms.ScaledTranslation object at 0x0000021CCF9DB290>, 'patch': <matplotlib.patches.Rectangle object at 0x0000021CCF9DB380>, 'axison': True, 'fmt_xdata': None, 'fmt_ydata': None, '_navigate': True, '_navigate_mode': None}
The issue is likely with how you are managing and interacting with the Matplotlib figures and axes within your Qt environment. Here's a breakdown of the problem and a solution:
Problem:
-
Conflicting Axes: You're likely creating an initial figure and axes using
self.fig = plt.figure()
and then trying to plot on different axes managed by yourDynamicSubplotManager
(details not shown in your code). This mismatch in axes references can lead to plots not appearing. -
Missing
draw()
ordraw_idle()
: After callingmpf.plot
, you must explicitly update the canvas to reflect the changes. You've usedself.canvas.draw_idle()
, but it's essential to ensure it's called at the right time and in the correct context of your Qt event loop.
Solution:
-
Consistent Axes Handling:
-
Method 1: Integrate with
DynamicSubplotManager
:-
Modify
DynamicSubplotManager
to accept an existing figure or axes during initialization. -
Pass
self.fig
or the desired axes toDynamicSubplotManager
so it controls the axes used for plotting.
-
Modify
-
Method 2: Direct Control:
-
If
DynamicSubplotManager
isn't strictly necessary, get the axes directly from your figure:python ax = self.fig.add_subplot(111) # For a single subplot mpf.plot(filtered_df[-100:], type='ohlc', ax=ax, style='charles', returnfig=True, warn_too_much_data=len(filtered_df))
-
If
-
Canvas Update: Ensure
self.canvas.draw_idle()
is called after thempf.plot
function to refresh the canvas.
Revised Code Structure (Illustrative):
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import mplfinance as mpf # Import mplfinance
# ... other imports and your DynamicSubplotManager class definition ...
class YourWidget(QtWidgets.QWidget): # Or your Qt widget class
def __init__(self):
# ... your initialization ...
self.fig = plt.figure()
self.canvas = FigureCanvas(self.fig)
# Assuming DynamicSubplotManager can work with an existing figure
self.d_axes_mgr = DynamicSubplotManager(self.fig)
def update_plot(self, filtered_df):
try:
# ... (Your data validation code) ...
# Get the correct axes from your DynamicSubplotManager
axes = self.d_axes_mgr.get_axes("your_subplot_key")
if axes:
mpf.plot(filtered_df[-100:], type='ohlc', ax=axes, style='charles',
returnfig=True, warn_too_much_data=len(filtered_df))
# Refresh the canvas
self.canvas.draw_idle()
except Exception as e:
print(f"Error in plotting: {e}")
Key Points:
-
Import mplfinance:
Ensure you have
mplfinance
installed (pip install mplfinance
) and imported correctly. -
Error Handling:
Use
try-except
blocks to catch potential errors during plotting for better debugging. - Qt Integration: The code provided assumes integration with a Qt application. Adapt it based on your specific Qt widget structure.
-
DynamicSubplotManager:
Without the implementation details of
DynamicSubplotManager
, the example provides a general approach. You'll need to adjust how you obtain the correctaxes
from it.
By carefully managing axes and ensuring canvas updates, your
mpf.plot
calls should work correctly within your Qt application.