Поместите ось X в координату Y 0 с помощью Plotly Python

#python #plotly

Вопрос:

Я хотел бы воспроизвести эту цифру на графике,
https://i.stack.imgur.com/bxWu8.png но у меня есть проблема, когда я пытаюсь воспроизвести горизонтальную линию центра, если я правильно понял, только оси могут отображать метки, но невозможно выбрать координату Y для расположения оси X.
Вот что мне до сих пор удалось воспроизвести
https://i.stack.imgur.com/7xUTk.png
У тебя есть идея?
заранее спасибо.

Ответ №1:

  • прямо вперед с plotly express
  • настройка трассировок texttemplate="%{text:.1%}", textposition="outside", textangle=90
  • настройка макета xaxis_type="category", yaxis_tickformat=".1%", yaxis_range=[-1.4, 1.4]
    1. xaxis_type="category" таким образом, каждый год отображается
    2. yaxis_range=[-1.4, 1.4] так что есть место для текста
 import numpy as np
import pandas as pd
import plotly.express as px

df = pd.DataFrame(
    {
        "year": np.repeat(range(2011, 2021), 2),
        "cat": np.tile(list("AB"), 10),
        "val": np.random.uniform(-1, 1, 20),
    }
)

px.bar(df, x="year", y="val", color="cat", text="val", barmode="group").update_traces(
    texttemplate="%{text:.1%}", textposition="outside", textangle=90
).update_layout(
    xaxis_type="category", yaxis_tickformat=".1%", yaxis_range=[-1.4, 1.4]
).update_yaxes(
    zeroline=True, zerolinewidth=2, zerolinecolor="black"
).update_yaxes(
    showline=True, linewidth=2, linecolor="black"
)
 

введите описание изображения здесь

более изощренный

  • галочки вдоль нулевой оси, метки галочек внизу рисунка
  • требуется два набора трассировок, один для положительных значений, а другой для отрицательных значений
  • ось x затем становится осью для маркеров тиков
  • xaxis2 затем становится осью для меток галочек
 trace_opts = dict(texttemplate="%{text:.1%}", textposition="outside", textangle=90)
data_opts = dict(color="cat", text="val", barmode="group")
y_opts = {
    "tickformat": ".1%",
    "showline": True,
    "linewidth": 2,
    "linecolor": "black",
}

# positive values
figp = px.bar(
    df, x="year", y=np.where(df["val"].ge(0), df["val"], np.nan), **data_opts
).update_traces(**trace_opts)

# negative values on separate axis
fign = px.bar(
    df, x="year", y=np.where(df["val"].lt(0), df["val"], np.nan), **data_opts
).update_traces(**trace_opts, showlegend=False, yaxis="y2", xaxis="x2")

# integrate and format both sets of axis
figp.add_traces(fign.data).update_layout(
    yaxis={"domain": [0.5, 1], "range": [0, 1.5], **y_opts},
    yaxis2={"domain": [0, 0.5], "range": [-1.5, 0], **y_opts},
    xaxis=dict(
        type="category",
        ticklen=7, tickwidth=3,
        tickson="labels",
        ticks="outside",
        showticklabels=False,
    ),
    xaxis2=dict(type="category", anchor="free"),
).update_layout(xaxis_title="", xaxis2_title=figp.layout.xaxis.title)
 

введите описание изображения здесь

Комментарии:

1. Спасибо за ваш ответ, я также хотел бы, чтобы на нулевой линии была линия, которая отмечает разделение между тиками, это то, что я застрял выше, мне не удалось найти способ достичь этого.

2. обновлено — это становится намного сложнее рассмотреть. нужно 2*оси и 2*оси

3. Большое вам спасибо, мне кажется, это лучшее решение. Хорошая работа.