Setting legend text colour in Plotly 3.0 - python

I have just installed the lastest Plotly (3.0) and I have not been able to set the legend text colour.
This is my code:
import plotly.graph_objs as go
import numpy as np
x = np.random.randn(1000)
y = np.random.randn(1000)
fig = go.FigureWidget({'x':x,'y':y,'type':'histogram2dcontour','colorscale':'Viridis'}],
layout=go.Layout(title='test',width=700,plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)'))
fig.layout.titlefont.color = 'orange'
fig.layout.xaxis.color = 'white'
fig.layout.yaxis.color = 'white'
fig.layout.legend.font.size = 2000
fig.layout.legend.font.color = 'red'
fig
As can be seen below the legend text below remains the same. Weirdly the attributes of fig.layout.legend.font.color include capitalise, isdigit class methods etc.
Is this a bug or am I missing something?
Any help much appreciated.
Thanks.

Because you are using histogram2contour the color-bar on the right is not a legend but actually an object called colorbar. To update it you can configure it's properties in your trace. I have an example below where I make the tick marks orange and the title red. I used Jupyter Notebooks to create the example so I had to configure it to offline but you don't have too. Here is the documentation for the color-bar object.
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)
import numpy as np
x = np.random.uniform(-1, 1, size=500)
y = np.random.uniform(-1, 1, size=500)
trace = [go.Histogram2dContour(
x = x,
y = y,
colorbar=dict(
title='Colorbar',
tickfont={'color':'#E90' },
titlefont={"color":'#FF0000'}
),
)]
iplot(trace, filename = "Basic Histogram2dContour")

Related

Error bar information not displaying in Scatter3d hover

I have a 3d plot working with z_axis asymmetrical error bars, but when I hover over the data points, I'm only getting the (x,y,z) information instead of (x,y,z +err/-err).
Plotly documentation for the error bars indicates that this information should be automatically included in the hover label. I tried using the hovertext attribute (setting hoverinfo='text' per the Scatter3d docs) with no success. Perhaps my attempt at reformatting labels isn't in the format that plotly requires, but I've tried a few different ways now to no avail. Below is the code trying to use the hovertext and hoverinfo attributes.
import pandas as pd
import numpy as np
import plotly.plotly as py
import plotly.graph_objs as go
from plotly.offline import iplot, init_notebook_mode
import cufflinks as cf
cf.go_offline()
cf.set_config_file(world_readable=True,theme='pearl',offline=True)
init_notebook_mode()
x = [1,2,3,4,5]
y = [1,2,3,4,5]
z1 = [1,2,3,4,5]
z2 = np.multiply(z1,2)
z3 = np.multiply(z1,0.5)
df = pd.DataFrame({'A':x,'B':y,'C':z1,'D':z2,'E':z3})
test = []
for row in df.values:
test.append('x:{}; y:{}; z={} +{}/-{}'.format(row[0],row[1],row[2],row[3],row[4]))
fig = go.Figure()
fig.add_trace(
go.Scatter3d(
x=x,
y=y,
z=z1,
# https://plot.ly/python/reference/#scatter3d-error_z
error_z = dict(
visible=True,
type='data',
array=np.subtract(z2,z1),
arrayminus=np.subtract(z1,z3)
),
name='Test Plot',
marker=dict(size=4),
opacity = 1, # 1=default
mode='markers',
hovertext=test,
hoverinfo='text' # set this to 'text' if using 'hovertext' attr
)
)
fig.layout.update(scene = dict(
xaxis_title='X Axis',
yaxis_title='Y Axis',
zaxis_title='Output')
)
fig.show()

Plotly: How to set the range of the y axis?

I have the following code to create the line plot with Plotly. How can I set the range of Y axis to always have it in [0; 10]?
layout = go.Layout(
title=go.layout.Title(
text="Test",
xref='paper',
x=0
),
xaxis=go.layout.XAxis(
tickmode='linear',
tickfont=dict(
size=10
),
title=go.layout.xaxis.Title(
font=dict(
size=14,
color='#7f7f7f'
)
)
),
yaxis=go.layout.YAxis(
title=go.layout.yaxis.Title(
text=y,
font=dict(
size=14,
color='#7f7f7f'
)
)
)
)
data = [go.Scatter(x=x1, y=y1)]
Update for newer versions
When setting up a figure you can use plotly's magic underscore notation and specify layout_yaxis_range=[<from_value>, <to_value>] like this:
fig = go.Figure(data=go.Scatter(x=x, y=y, mode='lines'), layout_yaxis_range=[-4,4])
Or if you've already got a figure named fig, you can use:
fig.update_layout(yaxis_range=[-4,4])
And:
fig.update(layout_yaxis_range = [-4,4])
Or:
fig.update_yaxes(range = [-4,4])
Figure:
Complete code:
# imports
import pandas as pd
import plotly.graph_objs as go
import numpy as np
# data
np.random.seed(4)
x = np.linspace(0, 1, 50)
y = np.cumsum(np.random.randn(50))
# plotly line chart
fig = go.Figure(data=go.Scatter(x=x, y=y, mode='lines'), layout_yaxis_range=[-4,4])
fig.update_layout(yaxis_range=[-4,4])
fig.show()
Original answer using plotly.offline, iplot and no magic underscore notation:
When setting up a figure, use:
layout = go.Layout(yaxis=dict(range=[fromValue, toValue])
Or if you've already got a figure named fig, you can use:
fig.update_layout(yaxis=dict(range=[fromValue,toValue]))
Plot:
Complete code for Jupyter Notebook:
# imports
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
import pandas as pd
import plotly.graph_objs as go
import numpy as np
# setup
init_notebook_mode(connected=True)
# data
np.random.seed(4)
x = np.linspace(0, 1, 50)
y = np.cumsum(np.random.randn(50))
# line
trace = go.Scatter(
x=x,
y=y,
)
# layout
layout = go.Layout(yaxis=dict(range=[-4,4])
)
# Plot
fig = go.Figure(data=[trace], layout=layout)
iplot(fig)
Some important details:
With this setup, you can easily add an y axis title like this:
# layout
layout = go.Layout(yaxis=dict(range=[-4,4]), title='y Axis')
)
It's a little more tricky if you'd like to format that title further. I find it easiest to actually add another element with title = go.layout.yaxis.Title(text='y Axis', font=dict(size=14, color='#7f7f7f'). As long as you do it the right way, you should not experience the situation in your comment above:
Thanks. I tried it. But then I have 2 definitions of yaxis in the
Layout: yaxis=dict(range=[0, 10]) and yaxis=go.layout.YAxis. Therefore
an error appears.
Take a look at this:
Plot:
Complete code with y-axis text formatting:
# imports
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
import pandas as pd
import plotly.graph_objs as go
import numpy as np
# setup
init_notebook_mode(connected=True)
# data
np.random.seed(4)
x = np.linspace(0, 1, 50)
y = np.cumsum(np.random.randn(50))
# line
trace = go.Scatter(
x=x,
y=y,
)
# layout
layout = go.Layout(
yaxis=dict(range=[-4,4],
title = go.layout.yaxis.Title(text='y Axis', font=dict(size=14, color='#7f7f7f')))
)
# Plot
fig = go.Figure(data=[trace], layout=layout)
iplot(fig)
If I understand you right you want to limit the range of the y-axis itself. You can pass a dict in the keyword argument yaxis. It could be something like go.Layout(yaxis=dict(range=[0, 10])) I hope this helps you.

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