Python:如何在 Y 轴上绘制数字 [关闭]

Posted

技术标签:

【中文标题】Python:如何在 Y 轴上绘制数字 [关闭]【英文标题】:Python: How to plot numbers on Y-Axis [closed] 【发布时间】:2021-11-18 18:14:41 【问题描述】:

这是一张财务图表。 我希望在画布(图形)图表上绘制数字,将 x 轴作为时间序列,将 y 轴作为价格,我在照片编辑器上设计的示例图像以表明我的观点也共享将用于绘图的数据。

任何人都可以帮助我如何实现这个结果。以下原始数据在 15 分钟内重新采样,并按价格(LTP - 最后交易价格)分组。

Sharing raw data Example chart to plot

【问题讨论】:

请尝试将您的所有数据放在您的问题中而不是链接中,您想在条形图中表示此数据。 根据其他评论 - 数据作为文本 【参考方案1】: 你描述的是Scatter(mode="text")这是下面代码中的第二个跟踪 您的模拟图片还会在画布上的文本周围显示线条。这是由 bar 跟踪 完成的 大部分代码都在模拟您未提供的数据
import pandas as pd
import numpy as np
import plotly.graph_objects as go

# generate some sample data
df = (
    pd.DataFrame(
        index=pd.MultiIndex.from_product(
            [
                np.arange(326.75, 324.95, -0.05),
                pd.date_range("24-sep-2021 09:00", freq="15min", periods=6),
            ],
            names=["LTP", "Time"],
        )
    )
    .reset_index()
    .pipe(
        lambda d: d.assign(
            BuyVolume=np.random.choice(
                np.concatenate([[0], np.random.randint(0, 1000, (len(d)))]),
                len(d),
                p=[0.9] + [0.1 / len(d) for _ in range(len(d))],
            ),
            SellVolume=np.random.choice(
                np.concatenate([[0], np.random.randint(0, 1000, (len(d)))]),
                len(d),
                p=[0.9] + [0.1 / len(d) for _ in range(len(d))],
            ),
        )
    )
)

print(df.head(20).to_markdown())

# create text to appear on chart
df = df.assign(
    plotText=lambda d: d["BuyVolume"].astype(str) + "x" + d["SellVolume"].astype(str)
)
# only rows that have either a buy or sell volume
dfp = df.loc[df["plotText"].ne("0x0")]
# ranges for bars around the text
dfx = dfp.groupby("Time").agg(min=("LTP", "min"), max=("LTP", "max"))
fig = go.Figure(
    [
        go.Bar(
            x=dfx.index,
            y=dfx["max"] - dfx["min"],
            base=dfx["min"],
            marker="color":"white", "line":"color":"black", "width":3
        ),
        go.Scatter(x=dfp["Time"], y=dfp["LTP"], text=dfp["plotText"], mode="text"),
    ],
)
fig.update_layout(showlegend=False, template="plotly_white")


样本数据

LTP Time BuyVolume SellVolume
0 326.75 2021-09-24 09:00:00 0 0
1 326.75 2021-09-24 09:15:00 0 983
2 326.75 2021-09-24 09:30:00 0 74
3 326.75 2021-09-24 09:45:00 0 0
4 326.75 2021-09-24 10:00:00 0 0
5 326.75 2021-09-24 10:15:00 705 0
6 326.7 2021-09-24 09:00:00 0 0
7 326.7 2021-09-24 09:15:00 0 0
8 326.7 2021-09-24 09:30:00 0 0
9 326.7 2021-09-24 09:45:00 0 0
10 326.7 2021-09-24 10:00:00 0 0
11 326.7 2021-09-24 10:15:00 0 593
12 326.65 2021-09-24 09:00:00 0 630
13 326.65 2021-09-24 09:15:00 0 0
14 326.65 2021-09-24 09:30:00 0 968
15 326.65 2021-09-24 09:45:00 0 0
16 326.65 2021-09-24 10:00:00 0 0
17 326.65 2021-09-24 10:15:00 213 0
18 326.6 2021-09-24 09:00:00 0 0
19 326.6 2021-09-24 09:15:00 0 0

情节

堆叠条形和悬停

要在图表上绘制的文本过多 将数据编码成堆积条形图 使用rangesliderrangeselector 导航xaxis 第一个栏是必需的,因此rangeslider 清晰可见
import pandas as pd
import numpy as np
import plotly.graph_objects as go
import plotly.express as px
from pathlib import Path
import itertools

df = pd.read_csv(
    Path.home().joinpath("Downloads").joinpath("security_chart_WIPRO-EQ.csv")
)
df["Time"] = pd.to_datetime(df["Time"])
# df = df.sort_values("Time").head(200)

fig = px.bar(
    df.groupby("Time", as_index=False).agg(
        base=("LTP", "min"), y=("LTP", lambda s: s.max() - s.min())
    ),
    x="Time",
    y="y",
    base="base",
).update_traces(
    hoverinfo="none",
    hovertemplate="",
    marker="color": "white", "line": "color": "black", "width": 1,
)
fig.add_traces(
    px.bar(
        df.sort_values(["Time", "LTP"])
        .groupby("Time")
        .apply(
            lambda d: d.assign(
                y=(d["LTP"] - d["LTP"].shift()), color=np.linspace(0, 1, len(d))
            )
        ),
        x="Time",
        y="y",
        base="LTP",
        hover_name="volume",
        color="color",
        hover_data="color": False, "y": False,
    ).data
)
fig.update_layout(
    xaxis=
        "rangeselector": 
            "buttons": [
                dict(count=n, label=f"nhrs", step="hour", stepmode="backward")
                for n in [2, 4, 6, 8]
            ]
        ,
        "rangeslider": "visible": True,
        "range": [
            df["Time"].min() - pd.Timedelta(minutes=15),
            df["Time"].min() + pd.Timedelta(hours=4),
        ],
        "rangebreaks": [
            dict(bounds=[16, 9], pattern="hour"),
            dict(bounds=["sat", "mon"]),
        ],
    ,
    coloraxis="showscale": False,
    margin="l": 0, "r": 0, "t": 0, "b": 0,
    height=800,
)

【讨论】:

你好,我达到了结果,谢谢你的帮助,我想扩展这个查询。如您所见,文本彼此非常接近,难以理解,我希望这个空间足够让它变得可读,我尝试了缩放和平移,但结果并不令人满意。你能告诉如何解决这个问题,以便提高可读性。请单击此保管箱链接以参考产生结果的图像。 example output 你能提供数据而不是图像吗?我有一些想法,但最好使用实际数据而不是模拟数据 好的,附上数据链接Raw Data 我想要实现的是足迹图,如果你用谷歌搜索它并浏览谷歌的图像部分,你会看到很多示例图像。我使用了带有散点文本图的烛台子图。在我的情况下,情节在视觉上并不清晰。 任何更新 Rob,等待您的回复。你能解决这个问题吗?

以上是关于Python:如何在 Y 轴上绘制数字 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Python/MatPlotLib:无法在 y 轴上打印正确的数据

使用 Matplotlib 在 Python 中绘制时间

如何使用plotly js在y轴上为单个x轴值(可能是日期)绘制两个点

在 Y 轴上或 Python 中每个条形的顶部显示值 [关闭]

朴素贝叶斯和 SVM 分类 - 如何在 x y 轴上绘制精度?

如何在 R 中绘制回归树的预测值与实际值? [关闭]