简体   繁体   中英

Plotly: How to plot histogram in Root style showing only the contours of the histogram?

I want to make a histogram with this style:

用 Root 制作的直方图

But using plotly in Python. Ie I want to merge the bars and plot only the contour. I am using this code:

import plotly.graph_objects as go

import numpy as np

x = np.random.randn(500)
fig = go.Figure(data=[go.Histogram(x=x)])
fig.show()

I have been looking for examples on how to do this but could not find any.

Your best option is to handle the histogram with numpy like count, index = np.histogram(df['data'], bins=25) , and then use go.Scatter() and set the linetype to horizontal, vertical, horizontal with line=dict(width = 1, shape='hvh') . Take a look at the very last section why go.Histogram() will not be your best option. With a few other specifications for the layout of go.Scatter() , the snippet below will produce the following plot:

在此处输入图片说明

Complete code

import plotly.graph_objects as go
import pandas as pd
import numpy as np
import plotly.io as pio
import plotly.express as px

pio.templates.default = "plotly_white"

# random numbers to a df
np.random.seed(12)
df = pd.DataFrame({'data': np.random.randn(500)})

# produce histogram data wiht numpy
count, index = np.histogram(df['data'], bins=25)

# plotly, go.Scatter with line shape set to 'hvh'
fig = go.Figure()
fig.add_traces(go.Scatter(x=index, y = count,
                          line=dict(width = 1, shape='hvh')))

# y-axis cosmetics
fig.update_yaxes(
    showgrid=False,
    ticks="inside",
    tickson="boundaries",
    ticklen=10,
    showline=True,
    linewidth=1,
    linecolor='black',
    mirror=True,
    zeroline=False)

# x-axis cosmetics
fig.update_xaxes(
    showgrid=False,
    ticks="inside",
    tickson="boundaries",
    ticklen=10,
    showline=True,
    linewidth=1,
    linecolor='black',
    mirror=True,
    zeroline=False)

fig.show()

Why go.Scatter() and not go.Histogram() ?

The closest you'll get to your desired plot using your approach with fig = go.Figure(data=[go.Histogram(x=x)]) is this:

在此处输入图片说明

And that's pretty close, but you specifically wanted to exclude the vertical lines for each "bar". And I have yet not found a way to exclude or hide them with the go.Histogram setup.

Code for go.Histogram()

import plotly.graph_objects as go
import pandas as pd
import numpy as np
import plotly.io as pio
import plotly.express as px

pio.templates.default = "plotly_white"

import numpy as np

x = np.random.randn(500)
fig = go.Figure(data=[go.Histogram(x=x)])
fig.update_traces(marker=dict(color='rgba(0,0,0,0)', line=dict(width=1, color='blue')))
fig.show()
import plotly.graph_objects as go
import numpy as np
import pandas as pd

x = np.random.randn(100)

# build data frame that is histogram
df = pd.cut(x, bins=10).value_counts().to_frame().assign(
    l=lambda d: pd.IntervalIndex(d.index).left,
    r=lambda d: pd.IntervalIndex(d.index).right,
).sort_values(["l","r"]).rename(columns={0:"y"}).astype(float)

# lines in plotly are delimited by none
def line_array(df, cols):
    return np.pad(
        df.loc[:, cols].values, [(0, 0), (0, 1)], constant_values=None
    ).reshape(1, (len(df) * 3))[0]

# plot just lines
go.Figure(go.Scatter(x=line_array(df, ["l","r"]), y=line_array(df, ["y","y"]), marker={"color":"black"}))

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM