How to Change x-axis to logarithmic in PLOTLY histogram - python

How to make x-axis of the following histogram, logarithmic?
The following code:
data_list = [1,1,5,5,5,100,100]
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Histogram(x=data_list, nbinsx=100))
import plotly.offline as py
py.init_notebook_mode(connected=False)
py.offline.plot(fig, filename = 'test.html')
Produces typical histogram.
How can I change the x-axis logarithmic?
I also tried:
data_list = [1,1,5,5,5,100,100]
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Histogram(x=data_list, nbinsx=100))
fig.update_layout(xaxis_type="log")
fig.update_xaxes(tick0=0, dtick=1, range=[0,2.5])
import plotly.offline as py
py.init_notebook_mode(connected=False)
py.offline.plot(fig, filename = 'test.html')
but this will result in non-logarithmic bins, and essentially, the bin at 100 disappears!

As said above in the comments, logarithmic axes are not possible with plotly. You could try to create bins using numpy and create a bar plot with those.

Related

plot line over heatmap

hello im trying to make a heatmap with btc asks and bids, this graph will have a line representing the close price. im using :
plotly.expres as px
plotly.graph_objects as go
the code is :
go.Figure(go.Heatmap(x=df3["timestamp"], y=df2["asks"], z=df["baseVolume"])
px.line(df3, x="timestamp", y="close") ## not working
fig.show()
graph output
Since no data is presented, I have used the heatmap in the official reference as an example for my code. Since the heatmap seems to deal with categorical variables, we need to add two axes for the y-axis, so we add a subplot. If we set the line chart to the added second axis, the heatmap and the line chart will be superimposed.
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import datetime
import numpy as np
np.random.seed(1)
programmers = ['Alex','Nicole','Sara','Etienne','Chelsea','Jody','Marianne']
base = datetime.datetime.today()
dates = base - np.arange(180) * datetime.timedelta(days=1)
z = np.random.poisson(size=(len(programmers), len(dates)))
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(go.Heatmap(
z=z,
x=dates,
y=programmers,
colorscale='Viridis'))
fig.add_trace(go.Scatter(
mode='lines',
x=dates,
y=np.linspace(0,5, len(dates)).cumsum(),
line=dict(color='red',width=2)), secondary_y=True,)
fig.update_layout(
title='GitHub commits per day',
xaxis_nticks=36)
fig.show()

Scatter 3d in Plotly Express - Colab Notebook is not plotting with equal axes

Trying to plot a very simple 3d scatter plot with x,y,z axes all equal in length. It is not working.
Code:
'''
from mpl_toolkits import mplot3d
import pandas
from pandas import DataFrame
pt_num = 100
x = np.random.uniform(-10,10,size=(pt_num,2))
model = np.array([2,2]).reshape(-1,1)
y = np.dot(x,model)
data = np.hstack((x,y))
dats = {'x':data[:,0].squeeze(),'w':data[:,1].squeeze(),'y':data[:,2].squeeze()}
df = DataFrame(data=dats)
import plotly.express as px
fig = px.scatter_3d(df, x='x', y='w', z='y',width=1200, height=1200)
fig.update_layout(scene=dict(xaxis=dict(range=[-10,10]),yaxis=dict(range=[-10,10]),zaxis=dict(range=[-10,10])))
fig['layout'].update(width=1500, height=1500, autosize=False)
fig.show()
'''
Thank you for any help.
Asked too soon out of frustration. The answer is to add 'aspectmode="cube"' to the scene dict for fig.update_layout:
fig.update_layout(scene=dict(xaxis=dict(range=view_range),yaxis=dict(range=view_range),zaxis=dict(range=view_range),aspectmode="cube"))

Plotly: How to plot a cumulative "steps" histogram?

I am trying to plot a cumulative histogram using Plotly in python, but make it look like "steps", i.e. bars with no color and only the top line is displayed. Something like this:
Basically, I'm trying to reproduce the behavior of the following matplotlib code:
import matplotlib.pyplot as plt
plt.hist(x, cumulative=True, histtype='step')
So far, the best I've been able to do is:
import plotly.graph_objs as go
from plotly.offline import iplot
h = go.Histogram(x=x,
cumulative=dict(enabled=True),
marker=dict(color="rgba(0,0,0,0)",
line=dict(color="red", width=1)))
iplot([h])
Which results in something like:
So what's the trick?
If you're willing to handle the binning and accumulation before you plot the data, you can use a go.Scatter object with the shape property of the line set to 'hvh'.
Plot:
Code: Setup for a Jupyter Notebook
#imports
import plotly.plotly as py
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
import numpy as np
import pandas as pd
# qtconsole for debugging
#%qtconsole -- style vim
# Notebook settings
init_notebook_mode(connected=True)
# Some sample data
x = np.random.normal(50, 5, 500)
binned = np.histogram(x, bins=25, density=True)
plot_y = np.cumsum(binned[0])
# Line
trace1 = go.Scatter(
x=binned[1],
y=plot_y,
mode='lines',
name="X",
hoverinfo='all',
line=dict(color = 'rgb(1255, 0, 0)', shape='hvh'
)
)
data = [trace1]
# Layout
layout = dict(title = 'Binned data from normal distribution',
legend=dict(
y=0.5,
traceorder='reversed',
font=dict(
size=16
)
)
)
# Make figure
fig = dict(data=data, layout=layout)
# Plot
iplot(fig, filename='line-shapes')
I hope this is something you can use!
Don't hesitate to let me know if not.
Some details:
The data sample is made using np.random.normal(). x is a sampled normal distribution with mean = 50, sigma = 5 and 500 observations. x is then put in 50 bins using np.histogram() which returns two arrays. These are used as data source for the plot.
Possible alternative approaches:
I also tried using your snippet with some random sample data and include shape='hvh' in your line=dict(color="red", width=1). That did not seem to work though. I also considered modifying the layout of your go.Histogram() so that only the top line of the bars were plotted, but I don't think it's possible.
The accepted solution works but may be limiting as the bins are all of equal width. One approach is to use matplotlib to calculate stats, then plot with plotly:
# sample data
# I am not using a normal distribution on purpose so that the effect of varying bin widths is apparent.
x = np.random.rand(100)
# use matplotlib to get "n" and "bins"
# n_bins will affect the resolution of the cumilative histogram but not dictate the bin widths.
n_bins = 100
n, bins, patches = plt.hist(x, n_bins, density=True, histtype='step', cumulative=-1)
# use plotly (v3) to plot
data = []
trace = go.Scatter(
x=bins,
y=n,
mode='lines',
name= "test",
line=dict(
shape='hvh'
)
)
data.append(trace)
fig = go.Figure(data=data)
iplot(fig)
The result should look something like this:

How do I add space between the tick labels and the graph in plotly (python)?

If I create a horizontal bar graph using plotly, the labels for each bar are right up against the graph. I'd like to add some space/pad/margin between the label and the graph. How can I do this?
Example:
import plotly.offline as py
import plotly.graph_objs as go
labels = ['Alice','Bob','Carl']
vals = [2,5,4]
data = [go.Bar(x=vals, y=labels, orientation='h')]
fig = go.Figure(data)
py.iplot(fig)
Just use parameter pad in margin. Check example from docs here.
Code:
import plotly.offline as py
import plotly.graph_objs as go
labels = ['Alice','Bob','Carl']
vals = [2,5,4]
data = [go.Bar(x=vals, y=labels, orientation='h')]
layout = go.Layout(
margin=dict(
pad=20
),
title = 'hbar',
)
fig = go.Figure(data=data,layout=layout)
py.plot(fig, filename='horizontal-bar.html')
And plot should be looks something like that:
Shorter solution:
fig.update_layout(margin_pad=10)
I think you could add some code like this.
import plotly.offline as py
import plotly.graph_objs as go
labels = ['Alice','Bob','Carl']
vals = [2,5,4]
data = [go.Bar(x=vals, y=labels, orientation='h')]
layout = dict(yaxis=dict(ticksuffix=" "))
fig = go.Figure(data=data,layout=layout)
py.iplot(fig)
add a suffix will fix this problem easily. I have checked the reference plotly ref, it also have more suitable key named tickformat, but it hard to use so I didn't use it.

Python Plotly heatmap subplots - remove internal y-axis numbers and ticks

How do I remove the numbers and ticks from the internal y-axis in the Plot.ly heatmap subplot graph below? Both plots share the same y-axis range so there is no reason to show both.
import plotly.plotly as py
import plotly.graph_objs as go
from plotly import tools
import pandas as pd
import numpy as np
dfl = []
dfl.append(pd.DataFrame(np.random.random((100,100,))))
dfl.append(pd.DataFrame(np.random.random((100,100,))))
fig = tools.make_subplots(rows=1, cols=len(dfl) ,print_grid=False);
for index, a in enumerate(dfl):
sn = str(index)
data = go.Heatmap(
z=a.values.tolist(),
colorscale='Viridis',
colorbar=dict(title='units'),
)
fig.append_trace(data, 1, index+1)
fig['layout']['xaxis'+str(index+1)].update(title='xaxis '+str(index))
fig['layout']['yaxis1'].update(title='y-axis')
fig['layout'].update(height=600, width=800, title='heatmap subplots')
py.iplot(fig)
Simply pass the setting 'shared_yaxes=True' to the tools.make_subplots function call, that is:
fig = tools.make_subplots(rows=1, cols=len(dfl) ,print_grid=False, shared_yaxes=True)
Updated answer for newer versions of Plotly. Based upon the v4 migration guide.
Differences include
calling the make_subplots function from the plotly.subplots library, instead of plotly.tools, and
using fig.show inplace of py.iplot to show the figure in Jupyter.
The code below was tested in Plotly version 5.1.0 using Jupyter Notebook.
import plotly
import plotly.graph_objs as go
import pandas as pd
import numpy as np
dfl = []
dfl.append(pd.DataFrame(np.random.random((100,100,))))
dfl.append(pd.DataFrame(np.random.random((100,100,))))
fig = plotly.subplots.make_subplots(rows=1, cols=len(dfl) ,print_grid=False, shared_yaxes=True);
for index, a in enumerate(dfl):
sn = str(index)
data = go.Heatmap(
z=a.values.tolist(),
colorscale='Viridis',
colorbar=dict(title='units'),
)
fig.append_trace(data, 1, index+1)
fig['layout']['xaxis'+str(index+1)].update(title='xaxis '+str(index))
fig['layout']['yaxis1'].update(title='y-axis')
fig['layout'].update(height=600, width=800, title='heatmap subplots')
fig.show()
The output:

Categories