Prefijo del eje de las subtramas de Python

Aug 29 2020

Quiero el signo de la moneda como prefijo del eje x en una subtrama gráfica, los comandos están bien porque funcionan en otros lugares, pero parece que se reproduce cuando se integra con las funciones de la subtrama.

import pandas as pd
import numpy as np
import plotly.graph_objs as go
from plotly.subplots import make_subplots
import random

x = np.array(["France", "Spain", "Italy", "Chile"])

df = pd.DataFrame({"country": np.repeat(x, [10,10,10,10]).tolist(),
                       "rating": random.sample(range(0,100),40),
                      "price": random.sample(range(100,1000),40)})

scatter = make_subplots(rows = 2, cols = 2, shared_yaxes = True, shared_xaxes = True,
                        
                   subplot_titles = ("France", "Spain", "Italy", "Chile"),
                        x_title = "Price", y_title = "Rating"
                   )

scatter.add_trace(go.Scatter(x = df.loc[df["country"]=="France", "price"],
                            y = df.loc[df["country"]=="France", "rating"],
                            mode = "markers"),
                            row = 1, col = 1)

scatter.add_trace(go.Scatter(x = df.loc[df["country"]=="Spain", "price"],
                            y = df.loc[df["country"]=="Spain", "rating"],
                            mode = "markers"),
                            row = 1, col = 2)

scatter.add_trace(go.Scatter(x = df.loc[df["country"]=="Italy", "price"],
                            y = df.loc[df["country"]=="Italy", "rating"],
                            mode = "markers"),
                            row = 2, col = 1)

scatter.add_trace(go.Scatter(x = df.loc[df["country"]=="Chile", "price"],
                            y = df.loc[df["country"]=="Chile", "rating"],
                            mode = "markers"),
                            row = 2, col = 2)

scatter.update_layout(showlegend = False, plot_bgcolor = "white",
                     xaxis = dict(showtickprefix = "all", tickprefix = "£"))

scatter.show()

Si elimino los comandos compartidos de los ejes xey, la moneda aparecerá solo en la subtrama inferior izquierda, pero no quiero eliminar esto realmente.

¿Alguien sabe alguna forma de evitar esto, por favor?

Actualizar

Actualmente estoy creando el siguiente gráfico:

y quiero poder crear lo siguiente:

Respuestas

2 rpanai Aug 29 2020 at 04:27

Creo que esto es bastante similar a esta respuesta La idea es actualizar cada rastro usando for_each_xaxisy de la for_each_yaxissiguiente manera.

Datos

import pandas as pd
import numpy as np
import plotly.graph_objs as go
from plotly.subplots import make_subplots
import random

x = np.array(["France", "Spain", "Italy", "Chile"])

df = pd.DataFrame({"country": np.repeat(x, [10,10,10,10]).tolist(),
                       "rating": random.sample(range(0,100),40),
                      "price": random.sample(range(100,1000),40)})

Trama

scatter = make_subplots(rows = 2, cols = 2,
                        shared_yaxes = True, shared_xaxes = True,
                        subplot_titles = ("France", "Spain", "Italy", "Chile"),
                        x_title = "Price", y_title = "Rating")

scatter.add_trace(go.Scatter(x = df.loc[df["country"]=="France", "price"],
                            y = df.loc[df["country"]=="France", "rating"],
                            mode = "markers"),
                            row = 1, col = 1)

scatter.add_trace(go.Scatter(x = df.loc[df["country"]=="Spain", "price"],
                            y = df.loc[df["country"]=="Spain", "rating"],
                            mode = "markers"),
                            row = 1, col = 2)

scatter.add_trace(go.Scatter(x = df.loc[df["country"]=="Italy", "price"],
                            y = df.loc[df["country"]=="Italy", "rating"],
                            mode = "markers"),
                            row = 2, col = 1)

scatter.add_trace(go.Scatter(x = df.loc[df["country"]=="Chile", "price"],
                            y = df.loc[df["country"]=="Chile", "rating"],
                            mode = "markers"),
                            row = 2, col = 2)

# New stuff from here
scatter = scatter.update_layout(showlegend = False, plot_bgcolor = "white")

def update_y(y):
    y.update(matches=None)
    y.showticklabels=True
    
def update_x(x):
    x.update(matches=None)
    x.showticklabels=True
    x.tickprefix = "£"
    
scatter.for_each_yaxis(update_y)
scatter.for_each_xaxis(update_x)

Utilizando plotly.express

Si lo desea, eventualmente podría usar plotly express, pero en este caso también debe ocuparse de las anotaciones.


import plotly.express as px

fig = px.scatter(
           df,
           x="price",
           y="rating",
           color="country",
           facet_col="country",
           facet_col_wrap=2,
           facet_row_spacing=0.2, # default is 0.07 when facet_col_wrap is used
           facet_col_spacing=0.04, # default is 0.03
           )

fig = fig.update_layout(showlegend = False, plot_bgcolor = "white")
fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))

def update_y(y):
    y.update(matches=None)
    y.showticklabels=True
    y.title.text = ""
    
def update_x(x):
    x.update(matches=None)
    x.showticklabels=True
    x.tickprefix = "£"
    x.title.text = ""


fig.for_each_yaxis(update_y)
fig.for_each_xaxis(update_x)

extra_annotations =[
        go.layout.Annotation(
            {
                'showarrow': False,
                'text': 'Price',
                'x': 0.5,
                'xanchor': 'center',
                'xref': 'paper',
                'y': 0,
                'yanchor': 'top',
                'yref': 'paper',
                'yshift': -30,
                'font': dict(
                    # family="Courier New, monospace",
                    size=16,
                    # color="#ffffff"
                    ),

            }),
         go.layout.Annotation(
            {
                'showarrow': False,
                'text': 'Rating',
                'x': 0,
                'xanchor': 'center',
                'xref': 'paper',
                'y': 0.7,
                'yanchor': 'top',
                'yref': 'paper',
                'xshift': -40,
                'textangle': -90,
                'font': dict(
                    # family="Courier New, monospace",
                    size=16,
                    # color="#ffffff"
                    ),

            })
        ]

annotations = list(fig.layout.annotations) + extra_annotations
fig.update_layout( annotations=annotations)

FluffySheep1990 Sep 03 2020 at 13:37

Entonces descubrí cómo hacerlo, necesita actualizar las subparcelas individualmente con el código xaxisN_tickprefix = "£"con 'N' como número de parcela del gráfico. En este caso, estaba intentando actualizar los gráficos 3 y 4, el código completo y los gráficos a continuación.

import pandas as pd
import numpy as np
import plotly.graph_objs as go
from plotly.subplots import make_subplots
import random

x = np.array(["France", "Spain", "Italy", "Chile"])

df = pd.DataFrame({"country": np.repeat(x, [10,10,10,10]).tolist(),
                       "rating": random.sample(range(0,100),40),
                      "price": random.sample(range(100,1000),40)})

scatter = make_subplots(rows = 2, cols = 2, shared_yaxes = True, shared_xaxes = True,
                        
                   subplot_titles = ("France", "Spain", "Italy", "Chile"),
                        x_title = "Price", y_title = "Rating"
                   )

scatter.add_trace(go.Scatter(x = df.loc[df["country"]=="France", "price"],
                            y = df.loc[df["country"]=="France", "rating"],
                            mode = "markers"),
                            row = 1, col = 1)

scatter.add_trace(go.Scatter(x = df.loc[df["country"]=="Spain", "price"],
                            y = df.loc[df["country"]=="Spain", "rating"],
                            mode = "markers"),
                            row = 1, col = 2)

scatter.add_trace(go.Scatter(x = df.loc[df["country"]=="Italy", "price"],
                            y = df.loc[df["country"]=="Italy", "rating"],
                            mode = "markers"),
                            row = 2, col = 1)

scatter.add_trace(go.Scatter(x = df.loc[df["country"]=="Chile", "price"],
                            y = df.loc[df["country"]=="Chile", "rating"],
                            mode = "markers"),
                            row = 2, col = 2)

scatter.update_layout(showlegend = False, plot_bgcolor = "white",
                     #xaxis = dict(showtickprefix = "all", tickprefix = "£")  <- old code
                     xaxis3_tickprefix = "£", xaxis4_tickprefix = "£") #new code

scatter.update_xaxes(range = [0,1000]) #also added to ensure the axis align
scatter.update_yaxes(range = [0,100]) #also added to ensure the axis align

scatter.show()