plotly / plotly.py

The interactive graphing library for Python :sparkles: This project now includes Plotly Express!
https://plotly.com/python/
MIT License
15.93k stars 2.53k forks source link

add polar contour or heatmap #2024

Open rafa-guedes opened 4 years ago

rafa-guedes commented 4 years ago

Thanks for this really useful library. I was wondering if there is any intention to support heatmap / contour type plots in polar projection. Something like the figure below (done with matplotlib):

polar-contour

emmanuelle commented 4 years ago

Hi @rafa-guedes, you can open an issue in the Javascript library https://github.com/plotly/plotly.js/issues/new to discuss about a new trace for polar contour. If you want a fast solution, you can maybe adapt the figure factory for ternary contours https://github.com/plotly/plotly.py/blob/master/packages/python/plotly/plotly/figure_factory/_ternary_contour.py where the computation of contours is done in Python (using a scikit-image function, skimage.measure.find_contours) and then what is displayed is a scatter trace (for you a go.Scatterpolar). Would that work for you?

rafa-guedes commented 4 years ago

Thank you @emmanuelle I will have a go at this. It looks like it should be possible to create a polar heatmap type with plotly.js, using polarbar: https://codepen.io/jamesandrewjackson13/details/NOaEgg, but I didn't manage to reproduce it with plotly.py. Thanks for the suggestions and quick reply!

emmanuelle commented 4 years ago

This is a cute example :-). You can do the polar heatmap as follows

import numpy as np
import plotly.graph_objects as go
r, theta = np.mgrid[0.1:1:10j, 0:360:20j]
color = np.random.random(r.shape)
fig = go.Figure(go.Barpolar(
    r=r.ravel(),
    theta=theta.ravel(),
    marker_color=color.ravel()),)
fig.update_layout(polar_bargap=0)
fig.show()

image

We might add it to the documentation https://github.com/plotly/plotly.py/blob/master/doc/python/polar-chart.md at some point (or maybe you want to do it :-))

nicolaskruchten commented 4 years ago

Hah that’s such an awesome example, totally need to get it into the docs!

rafa-guedes commented 4 years ago

This is great thank you!!

rafa-guedes commented 4 years ago

@emmanuelle one thing I didn't manage to tweak with this Barpolar example was the radial axis ticks. For some reason the values do not match the actual radii values, if you look at this particular example you plotted for instance the values go from 0-5 while they should range from 0-1. The hover data do show the correct radii though...

Forcing the ticks in update_layout do not seem to help either:

fig.update_layout(
    polar_radialaxis_tickvals=[0, 0.25, 0.5, 1],
)

Screenshot from 2020-01-07 20-55-13

silvanbrummen commented 4 years ago

Hi @rafa-guedes,

While looking for Plotly contour polar plots I stumbled upon this issue. Did you eventually manage to create a contour type polar plot like you showed in your waves plot example?

rafa-guedes commented 4 years ago

@silvanbrummen I did manage to, working from the example suggested by @emmanuelle . Below is an example code (the result can be seen here: https://wavebuoy.oceanum.science/). In the example below dset is an xarray Dataset, dset.freq and dset.dir are 1d arrays of wave frequency and direction, and arr is a 2d array of energy density efth(freq, dir). Notice I needed to remove radii labels as the values shown are not correct as described in the post above. I'll try and organise this as a reproducible example.

r, theta = np.meshgrid(dset.freq.values, dset.dir.values)
r = r.ravel()
theta = theta.ravel()
arr = list(dset.efth.isel(time=0).values)

fig = go.Figure(
    go.Barpolar(
        r=r,
        theta=theta,
        opacity=1.0,
        marker={
            "colorscale": px.colors.sequential.dense,
            "showscale": False,
            "color": arr,
            "line_color": None,
            "line_width": 0,
            "cmin": 0,
            "cmax": 0.1,
        },
    )
)
fig.update_layout(
    margin={"l": margin, "r": margin, "b": margin, "t": margin},
    plot_bgcolor="#23272c",
    paper_bgcolor="#23272c",
    polar_bgcolor="yellow",
    height=450,
    width=450,
    showlegend=False,
    xaxis_color="#a3a7b0",
    yaxis_color="#a3a7b0",
    polar=dict(
        radialaxis_tickcolor="white",
        angularaxis_color="#a3a7b0",
        radialaxis_color="#a3a7b0",
        radialaxis_layer="above traces",
        angularaxis_direction="clockwise",
        radialaxis_tickvals=[],  # Radii ticks
        bargap=0,  # Ensure cells will touch
        bgcolor="rgb(230, 240, 240)",  # Background shows in the outer part of polar
        hole=0.05,  # Center gap
    ),
)
silvanbrummen commented 4 years ago

@rafa-guedes Thanks for the fast reply! Fancy website you guys have ;)

Creating a polar-barplot seems like an option indeed. However, the data I would like to visualise, a 360 degree water surface elevation plot, seems a bit more detailed and could really use the benefits of a contour plot.

I'll create a new issue about this topic in the Javascript library as suggested by @emmanuelle. Link to the issue

chriddyp commented 4 years ago

@rafa-guedes - That website is so awesome! Love to see bar polar charts used in that way. Would you be up for sharing your website on with the Show & Tell tag on the Dash Community Forum? https://community.plotly.com/tag/show-and-tell I think the community would really enjoy seeing your app as well as this nice Bar Polar heatmap trick 🙂

rafa-guedes commented 4 years ago

Good idea @chriddyp I have posted some note about the app in the forum!

coolbud140 commented 3 years ago

@rafa-guedes I was searching for polar contour plots and found your post. You guys have an awesome website and visualization. Would you be able to share a snippet of your code that was used to generate the plot shown on your website? Thanks

zhuokaizhao commented 3 years ago

@emmanuelle Hi, thanks for the great example. I am trying to fit two barpolar plots in one figure. I used the standard make_subplots function fig = plotly.tools.make_subplots(rows=1, cols=2) and then added traces (bipolar plots) to the figure with row and col position included. But it gives me the error below

ValueError: Trace type 'barpolar' is not compatible with subplot type 'xy' at grid position (1, 1)

May I know how should I fix this? Thank you!