I am working on a python dash app. I have created a 3d scatter plot based on a dataframe df. The points on the plot all have white outlines, and when they are clustered tightly, the outlines make it look messy. Is there a way to remove the outlines?
import plotly.plotly as py
import plotly.graph_objs as go
import pandas as pd
df = pd.read_csv("./data.csv")
data = [
go.Scatter3d(
x=df[x_axis],
y=df[y_axis],
z=df[z_axis],
mode='markers',
marker=dict(size=df['size_col']),
)
]
layout = go.Layout(
scene=dict(xaxis={'title': 'x'},
yaxis={'title': 'y'},
zaxis={'title': 'z'}),
margin={'l': 60, 'b': 40, 't': 10, 'r': 10},
legend={'x': 0, 'y': 1},
hovermode='closest'
)
fig = go.Figure(data=data, layout=layout)
py.iplot(fig, filename='simple-3d-scatter')
This is what it currently looks like for me: 3d scatter plot
It should be possible because when looking at https://plot.ly/python/3d-scatter-plots/#3d-scatter-plot-with-colorscaling, the plot does not have these white outlines.
Marker objects have their own line attributes.
data = [
go.Scatter3d(
x=df[x_axis],
y=df[y_axis],
z=df[z_axis],
mode='markers',
marker=dict(
size=df['size_col'],
line=dict(width=0)
),
)
]
Related
I'm working on bar chart using plotly express. I'd like to use discrete colours and set the opacity of each bar individually. At the moment I'm using the following code:
import plotly.express as px
df1 = pd.DataFrame(dict(score=[93.3, 93.3, 92, 88], model=['model1', 'model2', 'model3', 'model4']))
fig = px.bar(df1, x='score', y='model', color='model',
color_discrete_map={
"model1": "gray",
"model2": "rgb(255, 10, 10)",
"model3": "rgb(255, 10, 10)",
"model4": "rgb(255, 10, 10)"},
opacity=[1, 1, 0.1, 0.1])
fig.update_layout(xaxis_range=[80,100], xaxis_title='Score', yaxis_title='')
fig.show()
To generate the plot below:
I've tried adding separate opacities using a list of values, but that doesn't seem to work. Instead, plotly takes the first value in the list and applies it to all the bar charts.
How can I add opacity to each bar individually?
I have not verified that this technique works for all plotly, but you can set the alpha value in the format 'rgba(255,10,10,0.5)' in the color specification.
import plotly.express as px
import pandas as pd
df1 = pd.DataFrame(dict(score=[93.3, 93.3, 92, 88], model=['model1', 'model2', 'model3', 'model4']))
fig = px.bar(df1, x='score', y='model', color='model',
color_discrete_map={
"model1": "gray",
"model2": "rgb(255, 10, 0)",
"model3": "rgba(255, 10, 10, 0.5)",
"model4": "rgba(255, 10, 10, 0.3)"},
#opacity=[1, 1, 0.1, 0.1]
)
fig.update_layout(xaxis_range=[80,100], xaxis_title='Score', yaxis_title='')
fig.show()
This can be done by digging deeper into plotly's Bar object.
Import plotly.graph_objects along with plotly.express with the following code:
import plotly.express as px
import plotly.graph_objects as go
With those imported you can create the chart object and then add the bars one by one to get the result you want:
# Create the initial bar chart
fig = px.bar()
# Add the bar chart for model 1, set its opacity to 0.3
fig.add_trace(
go.Bar(
x=[88],
y=['model1'],
opacity=0.3,
orientation='h',
marker=dict(color='rgb(255, 10, 10)')
)
)
# Add the bar chart for model 2, set its opacity to 0.65
fig.add_trace(
go.Bar(
x=[92],
y=['model2'],
opacity=0.65,
orientation='h',
marker=dict(color='rgb(255, 10, 10)')
)
)
fig.show()
This will give you something like the following:
As you can see, newly added bars automatically go to the top of the chart, so bare that in mind when you're setting up your own chart.
I wanted to create an interactive plot with matplotlib in google colab. It seems like a complex task so I want a little help to convert this piece of code which is in matplotlib to Plotly.
close = df['A']
fig = plt.figure(figsize = (15,5))
plt.plot(close, color='r', lw=2.)
plt.plot(close, '^', markersize=10, color='m', label = 'signal X', markevery = df_x)
plt.plot(close, 'v', markersize=10, color='k', label = 'signal Y', markevery = df_y)
plt.title('Turtle Agent: total gains %f, total investment %f%%'%(df_A, df_B))
plt.legend()
plt.show()
using sample data from plotly OHLC examples https://plotly.com/python/ohlc-charts/
create a line trace
add scatter traces based on filters of data frame with required formatting. This is done as a list comprehension, could be done as inline code
import pandas as pd
import numpy as np
import plotly.express as px
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv"
)
df["Date"] = pd.to_datetime(df["Date"])
# make data set more useful for demonstrating this plot
df.loc[df.sample((len(df)//8)*7).index, "direction"] = np.nan
px.line(df, x="Date", y="AAPL.Close").update_traces(line_color="red").add_traces(
[
px.scatter(
df.loc[df["direction"].eq(filter)], x="Date", y="AAPL.Close"
)
.update_traces(marker=fmt)
.data[0]
for filter, fmt in zip(
["Increasing", "Decreasing"],
[
{"color": "black", "symbol": "triangle-up", "size": 10},
{"color": "blue", "symbol": "triangle-down", "size": 10},
],
)
]
)
I would like to do something quite similar to the picture with plotly on python. I tried to find a way with subplots and shared_axis but no way to find a correct way. Is it possible to share the x axis of a bar chart with the column titles of a table?
graph bar with shared xaxis
this can be simulated with two traces
first trace is a standard bar chart, with yaxis domain constrained to 80% of the figure
second trace is a bar showing values as text and a fixed height against a second yaxis. yaxis2 is constrained to 10% of the domain
import plotly.express as px
import pandas as pd
import numpy as np
df = pd.DataFrame({"year": range(2011, 2022)}).assign(
pct=lambda d: np.random.uniform(-0.08, 0.08, len(d))
)
px.bar(df, x="year", y="pct").add_traces(
px.bar(df, x="year", y=np.full(len(df), 1), text="pct")
.update_traces(
yaxis="y2",
marker={"line": {"color": "black", "width": 1.5}, "color": "#E5ECF6"},
texttemplate="%{text:,.2%}",
)
.data
).update_layout(
yaxis={"domain": [0.2, 1], "tickformat": ",.2%"},
yaxis2={"domain": [0, 0.1], "visible": False},
xaxis={"title": "", "dtick": 1},
)
I am trying to create a plot using plotly with multiple axes. And for this, I am using the following code:
#Plotly libraries and options for graphic logic
from plotly.io import to_html
import plotly.io as pio
pio.renderers.default='browser'
import plotly.graph_objects as go
#Generic libraries
import pandas as pd
import numpy as np
from datetime import datetime
input_df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
threshold =2.8
name_yaxis="Gap"
input_df["AAPL.High"] = (input_df["AAPL.High"]-min(input_df["AAPL.High"]))*(threshold)/(max(input_df["AAPL.High"])-min(input_df["AAPL.High"]))+np.random.uniform(0.3,0.4,1)
ID_TAIL = "ID_1"
fig = go.Figure()
fig.add_trace(go.Scatter(x=input_df['Date'], y=input_df['AAPL.High'],
mode='lines+markers',
marker_size=12,
line = dict(color="#C4C4C4"),
marker=dict(color=( (0 < input_df['AAPL.High']) & (input_df['AAPL.High'] < threshold)).astype('int'),
colorscale=[[0, '#A51890'], [1, '#3BBFFE']]
),
showlegend=False,
xaxis="x1",
name = ""
)
)
my_x = [ID_TAIL + "_" +format(i, '04d') + "_0" for i in range(1,input_df.shape[0])]
fig.add_trace(go.Scatter(x=my_x, y=input_df['AAPL.High'],
mode='lines+markers',
marker_size=12,
line = dict(color="#C4C4C4"),
marker=dict(color=( (0 < input_df['AAPL.High']) & (input_df['AAPL.High'] < threshold)).astype('int'),
colorscale=[[0, '#A51890'], [1, '#3BBFFE']]
),
showlegend=False,
xaxis="x2",
name = ""
)
)
#== Add title boxes ==#
# Add title legend for box status
fig.add_annotation( text="<b>Health status<b>", xref="paper", yref="paper",
x=1.02, xanchor="left",
y=0.9, yanchor="bottom", # Same y as legend below
showarrow=False,
font = dict(family = "Roboto", size = 10))
#== End ==#
My problem is that as you can see in the following image, the ticks are overlapping:
So, my question is, how to create space between them?
Thanks in advance.
Here's a quick fix. Pop this line at the bottom of your code, and it will move xaxis2 to the top of the graph:
fig.update_layout({'xaxis2': {'side': 'top', 'tickangle': 45, 'nticks': 50}})
Output:
Shifting the secondary xaxis to the top will look like this.
Another Option:
Another approach would be to concatenate the axis titles into a single string, and display the concatenated string on the x-axis. This SO answer demonstrates this logic.
You can reduce the number of ticks by adding the following line
fig.update_layout(xaxis={'nticks': 8, 'tickangle': 90}, xaxis2={'nticks': 8, 'tickangle': 90})
Depending on the size of the plot, ticks may still overlap. In that case, you can either further reduce the tick number or hardcode the tick positions:
tickvalsX = ['2015-07', '2016-01', '2016-07', '2017-01']
tickvalsY = ['ID_1_0001_0', 'ID_1_00100_0', 'ID_1_0200_0', 'ID_1_0300_0', 'ID_1_0400_0', 'ID_1_0500_0']
fig.update_layout(xaxis={'tickmode': 'array', 'tickangle': 90, 'tickvals': tickvalsX}, xaxis2={'tickmode': 'array', 'tickangle': 90, 'tickvals': tickvalsY})
Further style elements of the axis you can find in the Plotly reference.
I have plotted a figure with 2 subplots, each with different scales. Everything plots correctly, except the colorscales are both plotted on the right and completely overlap - they are are not readable. I cannot find out how to position/reposition the individual subplot scales. I have included my code below. Thanks.
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
df = pd.read_csv(entry)
custColorscale = [[0, 'green'], [0.5, 'red'], [1, 'rgb(50, 50, 50)']]
fig = make_subplots(
rows=1, cols=2, subplot_titles=('one', 'two'))
fig.add_trace(
go.Scatter(x=df['tO'],
y=df['t1'],
mode='markers',
marker=dict(colorscale=custColorscale,
cmin=0, cmax=2,
size=6, color=df['Var1'],
showscale=True),
text=df['Var2']),
1, 1)
fig.add_trace(
go.Scatter(x=df['tO'],
y=df['t1'],
mode='markers',
marker=dict(
size=6, color=df['Var2'],
showscale=True),
text=df['Var2']),
1, 2)
fig.update_layout(height=700, width=1900,
title='Raw data')
fig.update_layout(coloraxis=dict(
colorscale='Bluered_r'))
fig.write_html(fig, file='raw plots.html', auto_open=True)
Looking through the Plotly documentation you find this which provide some hints as to how to solve the problem. Scroll to the 'marker' attributes and you will find that it has sub-attribute called 'colorbar'. The colorbar in turn has multiple options that could help set the plot the way you want. Particularly you find the 'x', 'y' and 'len' attributes of the colorbar very useful. You can use them to position the scales.
This question is also related to this but for a contour plot - you are making a scatterplot which is why the scatterplot reference would be what one should search.
A minimal working example (MWE) is shown below but with a toy dataset.
## make necessary imports
import numpy as np
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import pandas as pd
## make a fake dataset with pandas
d = {'t0': [i for i in np.arange(0.,10.,1.)], 't1': [i for i in
np.arange(10.,20.,1.)],'Var1': [i for i in np.arange(20.,30.,1.)],'Var2':
[i for i in np.arange(30.,40.,1.)] }
df = pd.DataFrame(data=d) #the dataset is made to mock the example code you provided
And for your plot you have the following :
# make subplots
custColorscale = [[0, 'green'], [0.5, 'red'], [1, 'rgb(50, 50, 50)']]
fig = make_subplots(
rows=1, cols=2, subplot_titles=('one', 'two'),horizontal_spacing = 0.4)
# plot 1
fig.add_trace(
go.Scatter(x=df['t0'],
y=df['t1'],
mode='markers',
marker=dict(colorscale=custColorscale,
cmin=0, cmax=2,
size=6, color=df['Var1'],
showscale=True,colorbar=dict(len=1.05, x=0.35
,y=0.49)), text=df['Var2']), 1, 1)
## plot 2
fig.add_trace(
go.Scatter(x=df['t0'],
y=df['t1'],
mode='markers',
marker=dict(
size=6, color=df['Var2'],
showscale=True,colorbar=dict(len=1.05, x=1.2 , y=0.49)),
text=df['Var2']),
1, 2 )
# show plots
fig.update_layout(height=500, width=700,
title='Raw data')
fig.update_layout(coloraxis=dict(
colorscale='Bluered_r'))
fig.show()
The only additions were:
The colorbar attribute of the marker.
The horizontal spacing to allow space for the first scale.
Feel free to play with these attributes.
I hope this helps!
Best regards.