当前位置: 首页 > 知识库问答 >
问题:

如何使matplotlib OHLC烛台图的y轴显示显示OHLC值而不是y轴光标位置

索寒
2023-03-14

我正在使用matplotlib创建OHLC烛台股价图。我正在使用mpl_finance的烛台ohlc模块创建图表。创建图表很简单,但是图表底部的x轴和y轴显示的是给定光标位置的日期和y轴值,但我希望x轴和y轴显示的是日期和日期打开、高、低、关闭(ohlc)值,而不仅仅是日期和y轴光标位置值。quotes数据集的格式为元组列表,其中每个元组包含日期,数字后跟open、high、low、close和volume。我试图使用matplotlib的format_coord函数来指定ohlc值,但我不知道如何让format_coord函数接受包含日期和相关ohlc值的列表作为输入,然后给出所需的日期和ohlc输出。下面是我编写的一些简化代码,它展示了我的问题:下面的代码现在已被修改,以使其完全工作:

import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter, WeekdayLocator, DayLocator, MONDAY
from mpl_finance import candlestick_ohlc
from matplotlib.dates import date2num, num2date


def ohlc_daily_date_axis():
    mondays = WeekdayLocator(MONDAY)  
    alldays = DayLocator()            
    weekFormatter = DateFormatter('%b %d %Y')  # e.g., Jan 12 2018

    quotes = [(737042.0, 2.72, 2.78, 2.6815, 2.74, 414378.0),
              (737045.0, 2.71, 2.77, 2.57, 2.63, 578841.0),
              (737046.0, 2.64, 2.64, 2.4228, 2.47, 1451450.0),
              (737047.0, 2.9, 3.15, 2.7, 2.96, 7230260.0),
              (737048.0, 2.92, 3.29, 2.67, 2.83, 2784110.0),
              (737049.0, 2.78, 2.82, 2.4701, 2.51, 822776.0),
              (737052.0, 2.56, 2.6344, 2.49, 2.5, 278883.0),
              (737054.0, 2.5, 2.619, 2.34, 2.6, 606002.0),
              (737055.0, 2.57, 2.63, 2.45, 2.57, 1295820.0),
              (737056.0, 2.57, 2.75, 2.51, 2.65, 435838.0)]

    fig, ax = plt.subplots(figsize=(18,5))
    plt.subplots_adjust(bottom=0.2)
    ax.xaxis.set_major_locator(mondays)
    ax.xaxis.set_minor_locator(alldays)
    ax.xaxis.set_major_formatter(weekFormatter)

    candlestick_ohlc(ax, quotes, width=0.6)

    ax.xaxis_date()
    ax.autoscale_view()
    plt.setp(plt.gca().get_xticklabels(), rotation=45, 
horizontalalignment='right')
    #the following line puts the ohlc data in the y axis display
    ax.format_coord = get_ohlc_from_date_xy
    # the following line puts the ohlc data in the x axis display
    #ax.fmt_xdata = get_ohlc_from_date_x

    plt.show()

def get_ohlc_from_date_x(dateasnum):
    print('dateasnum: ', int(dateasnum))
    quotes = [(737042.0, 2.72, 2.78, 2.6815, 2.74, 414378.0),
              (737045.0, 2.71, 2.77, 2.57, 2.63, 578841.0),
              (737046.0, 2.64, 2.64, 2.4228, 2.47, 1451450.0),
              (737047.0, 2.9, 3.15, 2.7, 2.96, 7230260.0),
              (737048.0, 2.92, 3.29, 2.67, 2.83, 2784110.0),
              (737049.0, 2.78, 2.82, 2.4701, 2.51, 822776.0),
              (737052.0, 2.56, 2.6344, 2.49, 2.5, 278883.0),
              (737054.0, 2.5, 2.619, 2.34, 2.6, 606002.0),
              (737055.0, 2.57, 2.63, 2.45, 2.57, 1295820.0),
              (737056.0, 2.57, 2.75, 2.51, 2.65, 435838.0)]
    for i in range(len(quotes)):
        if int(dateasnum) == quotes[i][0]:
            open = quotes[i][1]
            high = quotes[i][2]
            low = quotes[i][3]
            close = quotes[i][4]
            vol = quotes[i][5]
    dte = str(num2date(dateasnum).date())
    print('type(dte): ', type(dte))
    print('open: ', open)
    ohlc_str = dte + ' open: ' + str(open) + ' high: ' + str(high) + ' 
low: ' + str(low) + ' close: ' + str(close) + ' vol: ' + str(int(vol)) 
+ '    '

    return ohlc_str



def get_ohlc_from_date_xy(dateasnum,y):
    print('dateasnum: ', int(dateasnum))
    quotes = [(737042.0, 2.72, 2.78, 2.6815, 2.74, 414378.0),
              (737045.0, 2.71, 2.77, 2.57, 2.63, 578841.0),
              (737046.0, 2.64, 2.64, 2.4228, 2.47, 1451450.0),
              (737047.0, 2.9, 3.15, 2.7, 2.96, 7230260.0),
              (737048.0, 2.92, 3.29, 2.67, 2.83, 2784110.0),
              (737049.0, 2.78, 2.82, 2.4701, 2.51, 822776.0),
              (737052.0, 2.56, 2.6344, 2.49, 2.5, 278883.0),
              (737054.0, 2.5, 2.619, 2.34, 2.6, 606002.0),
              (737055.0, 2.57, 2.63, 2.45, 2.57, 1295820.0),
              (737056.0, 2.57, 2.75, 2.51, 2.65, 435838.0)]
    for i in range(len(quotes)):
        if int(dateasnum) == quotes[i][0]:
            open = quotes[i][1]
            high = quotes[i][2]
            low = quotes[i][3]
            close = quotes[i][4]
            vol = quotes[i][5]
    dte = str(num2date(dateasnum).date())
    #print('type(dte): ', type(dte))
    #print('open: ', open)
    ohlc_str = 'open: ' + str(open) + ' high: ' + str(high) + ' 
low: ' + str(low) + ' close: ' + str(close) + ' vol: ' + str(int(vol))

    return dte, ohlc_str



# This def does not work
def format_coord(x,y, quotes):
    for i in range(len(quotes)):
        if int(x) == quotes[i]:
            open = quotes[i][1]
            high = quotes[i][2]
            low = quotes[i][3]
            close = quotes[i][4]
            vol = quotes[i][5]
    y = 'open: ' + open # I'm just using open to simplify things
    x = DateFormatter('%b %d %Y')
    return (x,y)


if __name__ == '__main__':
    ohlc_daily_date_axis()

如果按原样运行此代码,则会出现以下错误(这是我在使用错误的def格式_coord(x,y,引号)方法时遇到的错误):

File "/Users/Me/Mee/python_db_programs/learn_matplotlib_test.py", line 33, 
in ohlc_daily_date_axis
    ax.format_coord = format_coord(quotes)
TypeError: format_coord() missing 2 required positional arguments: 'y' 
and 'quotes'

如果我把斧头砍掉。format_coord=format_coord(引号)行然后代码运行正常,但在x和y显示中没有我想要的日期和ohlc值。如果您能提供帮助,我们将不胜感激。

我最终没有尝试更改y显示,而是将ohlc值添加到x显示。也就是说我换了斧头。format_-coord=将_-coord(引号)格式化为仅格式化x坐标(即ax)的命令。fmt_扩展数据,然后编写一个def,该def使用引号列表获取每个日期对应的ohlc数据:

ax.fmt_xdata = get_ohlc_from_date

而不是

ax.format_coord = format_coord(quotes)

然后添加了这个def:

def get_ohlc_from_date(dateasnum):
    print('dateasnum: ', int(dateasnum))
    quotes = [(737042.0, 2.72, 2.78, 2.6815, 2.74, 414378.0),
              (737045.0, 2.71, 2.77, 2.57, 2.63, 578841.0),
              (737046.0, 2.64, 2.64, 2.4228, 2.47, 1451450.0),
              (737047.0, 2.9, 3.15, 2.7, 2.96, 7230260.0),
              (737048.0, 2.92, 3.29, 2.67, 2.83, 2784110.0),
              (737049.0, 2.78, 2.82, 2.4701, 2.51, 822776.0),
              (737052.0, 2.56, 2.6344, 2.49, 2.5, 278883.0),
              (737054.0, 2.5, 2.619, 2.34, 2.6, 606002.0),
              (737055.0, 2.57, 2.63, 2.45, 2.57, 1295820.0),
              (737056.0, 2.57, 2.75, 2.51, 2.65, 435838.0)]
    for i in range(len(quotes)):
        if int(dateasnum) == quotes[i][0]:
            open = quotes[i][1]
            high = quotes[i][2]
            low = quotes[i][3]
            close = quotes[i][4]
            vol = quotes[i][5]
    dte = str(num2date(dateasnum).date())
    print('type(dte): ', type(dte))
    print('open: ', open)
    ohlc_str = dte + ' open: ' + str(open) + ' high: ' + str(high) + ' 
low: ' + str(low) + ' close: ' + str(close) + ' vol: ' + str(int(vol)) 
+ '    '

    return ohlc_str

也因为我使用matplotlibs dateasnum函数,我必须导入:

from matplotlib.dates import num2date

虽然这并没有用ohlc值替换y轴坐标,但它确实在x轴和y轴显示中提供了ohlc值

在弄清楚如何将ohlc值添加到x轴显示器后,我意识到我用于将ohlc值添加到x轴显示器的逻辑可以应用到y轴显示器,从而允许在y轴参数中显示ohlc值。这是通过使用斧头完成的。format_coord=format_coord命令,并创建一个新的def,将ohlc值分配给y轴返回值。我修改了我发布的原始代码,以便根据ax是否可用。format_coord=格式化_coord行或ax。fmt_xdata=get_ohlc_from_注释掉日期行确定ohlc值是作为x轴显示的一部分还是作为y轴显示的一部分显示

共有2个答案

吕扬
2023-03-14

您可以使用Plotly的烛台图表,内置您想要的一切。

这里有个例子

元组到数据框的序列

要做到这一点,您需要将数据放在一个包含列的数据框中[“日期”、“高”、“低”、“打开”、“关闭”],请查看pandas。数据帧。from_records,在数据帧从元组序列创建数据帧对象时将数据导入数据帧。

其他的

  • 你可能需要转换日期为datetime,看看pandas.to_datetime转换它

问题的答案

从ploly的留档:

hoverinfo–确定悬停时显示的跟踪信息。如果未设置“无”或“跳过”,则悬停时不显示任何信息。但是,如果未设置任何选项,则仍会触发单击和悬停事件。

同样值得一读:Python中的悬停文本和格式

最后审议

我知道这不是你想要的matplotlib制作的,但我认为这是一个相关的答案。

代码

def generatePlotly(df):
    layout = go.Layout(
        plot_bgcolor="#FFF",      # Sets background color to white
        hovermode="x",
        hoverdistance=100,        # Distance to show hover label of data point
        spikedistance=1000,       # Distance to show spike
        xaxis=dict(
            title="Data",         # X Axis Title
            linecolor="#BCCCDC",  # Sets color of X-axis line
            showgrid=False,       # Removes X-axis grid lines
            showspikes=True,      # Show spike line for X-axis
            gridcolor="#BCCCDC",  # Grid color, if enabled
            # Format spike - Show a Line at the pointer
            spikethickness=2,
            spikedash="dot",
            spikecolor="#999999",
            spikemode="across",
            fixedrange=True,
            spikesnap="cursor",
        ),
        yaxis=dict(
            title="Preço (R$)",   # Y Axis Title
            linecolor="#BCCCDC",  # Sets color of Y-axis line
            showgrid=False,       # Removes Y-axis grid lines
            gridcolor="#BCCCDC",  # Grid color, if enabled
            showspikes=True,      # Show spike line for X-axis
            # Format spike - Show a Line at the pointer
            spikethickness=2,
            spikedash="dot",
            spikecolor="#999999",
            spikemode="across",
            fixedrange=True,
            side="right",
            spikesnap="cursor",
        ),
        margin=go.layout.Margin(
            l=0,  # left margin
            r=0,  # right margin
            b=0,  # bottom margin
            t=0,  # top margin
        ),
    )

    fig = go.Figure(
        data=[
            go.Candlestick(
                x=df["Date"],      # Your data
                open=df["Open"],   
                high=df["High"],
                low=df["Low"],
                close=df["Close"],
            )
        ],
        layout=layout,
    )
    # Remove rangeslider from the chart, you can just comment the next line
    fig.update_layout(xaxis_rangeslider_visible=False)

    # Legend position
    fig.update_layout(legend=dict(yanchor="top", y=0.99, xanchor="left", x=0.01)) 

    ############################################################
    # For this part look at EXTRAS at the bottom of the answer #
    ############################################################
    # build complete timepline from start date to end date
    dt_all = pd.date_range(start=df["Date"].iloc[0], end=df["Date"].iloc[-1])
    # retrieve the dates that ARE in the original datset
    dt_obs = [d.strftime("%Y-%m-%d") for d in pd.to_datetime(df["Date"])]
    # define dates with missing values
    dt_breaks = [d for d in dt_all.strftime("%Y-%m-%d").tolist() if not d in dt_obs]
    fig.update_xaxes(
        rangebreaks=[
            # dict(bounds=["sat", "mon"]),  # hide weekends
            dict(values=dt_breaks)
        ]
    )

    # Hover Distance and Hover Info
    # fig.update_layout(hoverdistance=0)
    # fig.update_traces(xaxis="x", hoverinfo="none")

    fig.show()

额外费用

Plotly:如何设置Plotly地物的样式,使其不显示缺失日期的间隙?

谭志用
2023-03-14

下面的解决方案允许matplotlib OHLC烛台图的x轴和y轴读数在y轴读数中显示OHLC值,而不是在y轴光标位置。

import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter, WeekdayLocator, DayLocator, 
MONDAY
from mpl_finance import candlestick_ohlc
from matplotlib.dates import date2num, num2date


def ohlc_daily_date_axis():
    mondays = WeekdayLocator(MONDAY)  
    alldays = DayLocator()            
    weekFormatter = DateFormatter('%b %d %Y')  # e.g., Jan 12 2018

    quotes = [(737042.0, 2.72, 2.78, 2.6815, 2.74, 414378.0),
              (737045.0, 2.71, 2.77, 2.57, 2.63, 578841.0),
              (737046.0, 2.64, 2.64, 2.4228, 2.47, 1451450.0),
              (737047.0, 2.9, 3.15, 2.7, 2.96, 7230260.0),
              (737048.0, 2.92, 3.29, 2.67, 2.83, 2784110.0),
              (737049.0, 2.78, 2.82, 2.4701, 2.51, 822776.0),
              (737052.0, 2.56, 2.6344, 2.49, 2.5, 278883.0),
              (737054.0, 2.5, 2.619, 2.34, 2.6, 606002.0),
              (737055.0, 2.57, 2.63, 2.45, 2.57, 1295820.0),
              (737056.0, 2.57, 2.75, 2.51, 2.65, 435838.0)]

    fig, ax = plt.subplots(figsize=(18,5))
    plt.subplots_adjust(bottom=0.2)
    ax.xaxis.set_major_locator(mondays)
    ax.xaxis.set_minor_locator(alldays)
    ax.xaxis.set_major_formatter(weekFormatter)

    candlestick_ohlc(ax, quotes, width=0.6)

    ax.xaxis_date()
    ax.autoscale_view()
    plt.setp(plt.gca().get_xticklabels(), rotation=45, 
horizontalalignment='right')
    #the following line puts the ohlc data in the y axis display
    ax.format_coord = get_ohlc_from_date_xy
    # the following line puts the ohlc data in the x axis display
    #ax.fmt_xdata = get_ohlc_from_date_x

    plt.show()

def get_ohlc_from_date_x(dateasnum):
    print('dateasnum: ', int(dateasnum))
    quotes = [(737042.0, 2.72, 2.78, 2.6815, 2.74, 414378.0),
              (737045.0, 2.71, 2.77, 2.57, 2.63, 578841.0),
              (737046.0, 2.64, 2.64, 2.4228, 2.47, 1451450.0),
              (737047.0, 2.9, 3.15, 2.7, 2.96, 7230260.0),
              (737048.0, 2.92, 3.29, 2.67, 2.83, 2784110.0),
              (737049.0, 2.78, 2.82, 2.4701, 2.51, 822776.0),
              (737052.0, 2.56, 2.6344, 2.49, 2.5, 278883.0),
              (737054.0, 2.5, 2.619, 2.34, 2.6, 606002.0),
              (737055.0, 2.57, 2.63, 2.45, 2.57, 1295820.0),
              (737056.0, 2.57, 2.75, 2.51, 2.65, 435838.0)]
    for i in range(len(quotes)):
        if int(dateasnum) == quotes[i][0]:
            open = quotes[i][1]
            high = quotes[i][2]
            low = quotes[i][3]
            close = quotes[i][4]
            vol = quotes[i][5]
    dte = str(num2date(dateasnum).date())
    print('type(dte): ', type(dte))
    print('open: ', open)
    ohlc_str = dte + ' open: ' + str(open) + ' high: ' + str(high) + ' 
low: ' + str(low) + ' close: ' + str(close) + ' vol: ' + str(int(vol)) 
+ '    '

    return ohlc_str



def get_ohlc_from_date_xy(dateasnum,y):
    print('dateasnum: ', int(dateasnum))
    quotes = [(737042.0, 2.72, 2.78, 2.6815, 2.74, 414378.0),
              (737045.0, 2.71, 2.77, 2.57, 2.63, 578841.0),
              (737046.0, 2.64, 2.64, 2.4228, 2.47, 1451450.0),
              (737047.0, 2.9, 3.15, 2.7, 2.96, 7230260.0),
              (737048.0, 2.92, 3.29, 2.67, 2.83, 2784110.0),
              (737049.0, 2.78, 2.82, 2.4701, 2.51, 822776.0),
              (737052.0, 2.56, 2.6344, 2.49, 2.5, 278883.0),
              (737054.0, 2.5, 2.619, 2.34, 2.6, 606002.0),
              (737055.0, 2.57, 2.63, 2.45, 2.57, 1295820.0),
              (737056.0, 2.57, 2.75, 2.51, 2.65, 435838.0)]
    for i in range(len(quotes)):
        if int(dateasnum) == quotes[i][0]:
            open = quotes[i][1]
            high = quotes[i][2]
            low = quotes[i][3]
            close = quotes[i][4]
            vol = quotes[i][5]
    dte = str(num2date(dateasnum).date())
    #print('type(dte): ', type(dte))
    #print('open: ', open)
    ohlc_str = 'open: ' + str(open) + ' high: ' + str(high) + ' 
low: ' + str(low) + ' close: ' + str(close) + ' vol: ' + str(int(vol))

    return dte, ohlc_str






if __name__ == '__main__':
    ohlc_daily_date_axis()
 类似资料:
  • 我有一张图表,我已经知道我需要的刻度数。有3个是分组条形图。我在绞尽脑汁想怎么强迫它。现在它显示0到我的数据集中的任何数字,并根据需要自动缩放。 默认情况下,假设我使用数字来缩放,但在这种情况下,它是Y轴上的正、中性、负(字面意思是这些标签),它们是与X轴上的特定日期相关的数据点(有2个分组条标记为AM/PM)。 图表。js文档似乎没有解释如何在ticks配置的数字之外进行调整,我也不确定如何将其

  • 问题内容: 我在制作具有日期数组和一堆PM 2.5值的散点图时遇到麻烦。我的列表如下所示: 问题答案: 设置大小 设置颜色 还有很多其他参数:http : //matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.scatter

  • 我正在尝试使用vue-chartjs和Chart.js(2.7.1)绘制线图。显示图形,但没有xAx和yAx标签。 这是我的选项对象: 我认为scales.xAxes.scaleLabel不起作用。

  • 我有以下代码来绘制熊猫数据帧的数据: 图是正确的,但图例中仅显示标签为的最后一行。如何在一个图例中获得所有3行?

  • 本文向大家介绍python画双y轴图像的示例代码,包括了python画双y轴图像的示例代码的使用技巧和注意事项,需要的朋友参考一下 很多时候可能需要在一个图中画出多条函数图像,但是可能y轴的物理含义不一样,或是数值范围相差较大,此时就需要双y轴。 matplotlib和seaborn都可以画双y轴图像。 一个例子: 以上这篇python画双y轴图像的示例代码就是小编分享给大家的全部内容了,希望能给

  • 我在我的squarespace站点上使用了一些HTML&CSS来创建一个自定义的跟随光标。我只想有一个浮动的圆圈,没有实际的光标显示。我已经得到了它的工作,但当我的网站滚动跟随光标没有移动的页面滚动,只是卡在顶部。 这只会导致follow光标完全停止随鼠标移动而移动,在页面中心变成静态的。 将HTML&CSS注入到squarespace站点以创建自定义跟随光标: null null