首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用shiro安全管理

使用shiro安全管理

作者头像
dalaoyang
发布于 2018-06-13 07:44:22
发布于 2018-06-13 07:44:22
2.9K00
代码可运行
举报
文章被收录于专栏:dalaoyangdalaoyang
运行总次数:0
代码可运行

之前介绍了springboot使用security进行权限管理,这篇文件介绍一下springboot使用shiro进行安全管理。

简述本文的场景,本文使用springboot1.5.9+mysql+jpa+thymeleaf+shiro制作一个简单的验证,其中有2个角色,分别是admin和user,admin可以使用select和delete功能,user只能使用select功能。

新建项目,加入shiro依赖,pom文件如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.dalaoyang</groupId>
    <artifactId>springboot_shiro</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springboot_shiro</name>
    <description>springboot_shiro</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
            <version>1.9.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

配置文件如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
##端口号
server.port=8888



##数据库配置
##数据库地址
spring.datasource.url=jdbc:mysql://localhost:3306/shiro?characterEncoding=utf8&useSSL=false
##数据库用户名
spring.datasource.username=root
##数据库密码
spring.datasource.password=root
##数据库驱动
spring.datasource.driver-class-name=com.mysql.jdbc.Driver


##validate  加载hibernate时,验证创建数据库表结构
##create   每次加载hibernate,重新创建数据库表结构,这就是导致数据库表数据丢失的原因。
##create-drop        加载hibernate时创建,退出是删除表结构
##update                 加载hibernate自动更新数据库结构
##validate 启动时验证表的结构,不会创建表
##none  启动时不做任何操作
spring.jpa.hibernate.ddl-auto=update

##控制台打印sql
spring.jpa.show-sql=true


# 建议在开发时关闭缓存,不然没法看到实时页面
spring.thymeleaf.cache=false
##去除thymeleaf的html严格校验
spring.thymeleaf.mode=LEGACYHTML5

创建了三个实体类,分别是 SysUser(用户表)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.dalaoyang.entity;

import org.hibernate.validator.constraints.NotEmpty;

import javax.persistence.*;
import java.io.Serializable;
import java.util.List;

/**
 * @author dalaoyang
 * @Description
 * @project springboot_learn
 * @package com.dalaoyang.entity
 * @email yangyang@dalaoyang.cn
 * @date 2018/5/2
 */
@Entity
public class SysUser implements Serializable {

    @Id
    @GeneratedValue
    private Integer userId;
    @NotEmpty
    private String userName;
    @NotEmpty
    private String passWord;

    //多对多关系
    @ManyToMany(fetch= FetchType.EAGER)
    //急加载,加载一个实体时,定义急加载的属性会立即从数据库中加载
    //FetchType.LAZY:懒加载,加载一个实体时,定义懒加载的属性不会马上从数据库中加载
    @JoinTable(name = "SysUserRole", joinColumns = { @JoinColumn(name = "userId") },
            inverseJoinColumns ={@JoinColumn(name = "roleId") })
    private List<SysRole> roleList;// 一个用户具有多个角色


    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    public List<SysRole> getRoleList() {
        return roleList;
    }

    public void setRoleList(List<SysRole> roleList) {
        this.roleList = roleList;
    }
}

SysRole(角色表)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.dalaoyang.entity;

import org.hibernate.validator.constraints.NotEmpty;

import javax.persistence.*;
import java.io.Serializable;
import java.util.List;

/**
 * @author dalaoyang
 * @Description
 * @project springboot_learn
 * @package com.dalaoyang.entity
 * @email yangyang@dalaoyang.cn
 * @date 2018/5/2
 */
@Entity
public class SysRole implements Serializable {

    @Id
    @GeneratedValue
    private Integer roleId;
    private String roleName;

    //多对多关系
    @ManyToMany(fetch= FetchType.EAGER)
    @JoinTable(name="SysRoleMenu",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="menuId")})
    private List<SysMenu> menuList;

    //多对多关系
    @ManyToMany
    @JoinTable(name="SysUserRole",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="userId")})
    private List<SysUser> userList;// 一个角色对应多个用户

    public Integer getRoleId() {
        return roleId;
    }

    public void setRoleId(Integer roleId) {
        this.roleId = roleId;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public List<SysMenu> getMenuList() {
        return menuList;
    }

    public void setMenuList(List<SysMenu> menuList) {
        this.menuList = menuList;
    }

    public List<SysUser> getUserList() {
        return userList;
    }

    public void setUserList(List<SysUser> userList) {
        this.userList = userList;
    }
}

SysMenu(菜单表)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.dalaoyang.entity;

import javax.persistence.*;
import java.io.Serializable;
import java.util.List;

/**
 * @author dalaoyang
 * @Description
 * @project springboot_learn
 * @package com.dalaoyang.entity
 * @email yangyang@dalaoyang.cn
 * @date 2018/5/2
 */
@Entity
public class SysMenu implements Serializable {

    @Id
    @GeneratedValue
    private Integer menuId;
    private String menuName;

    @ManyToMany
    @JoinTable(name="SysRoleMenu",joinColumns={@JoinColumn(name="menuId")},inverseJoinColumns={@JoinColumn(name="roleId")})
    private List<SysRole> roleList;

    public Integer getMenuId() {
        return menuId;
    }

    public void setMenuId(Integer menuId) {
        this.menuId = menuId;
    }

    public String getMenuName() {
        return menuName;
    }

    public void setMenuName(String menuName) {
        this.menuName = menuName;
    }

    public List<SysRole> getRoleList() {
        return roleList;
    }

    public void setRoleList(List<SysRole> roleList) {
        this.roleList = roleList;
    }
}

创建一个UserRepository用于查询用户信息:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.dalaoyang.repository;

import com.dalaoyang.entity.SysUser;
import org.springframework.data.repository.CrudRepository;

/**
 * @author dalaoyang
 * @Description
 * @project springboot_learn
 * @package com.dalaoyang.repository
 * @email yangyang@dalaoyang.cn
 * @date 2018/5/2
 */
public interface UserRepository extends CrudRepository<SysUser,Long> {

    SysUser findByUserName(String username);
}

创建几个前台页面进行测试,分别是: login.html:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
错误信息:<h4 th:text="${msg}"></h4>
<form action="" method="post">
    <p>账号:<input type="text" name="username" value="dalaoyang"/></p>
    <p>密码:<input type="text" name="password" value="123"/></p>
    <p><input type="submit" value="登录"/></p>
</form>
</body>
</html>

index.html

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
index
<br/>
<form th:action="@{/logout}" method="post">
    <p><input type="submit" value="注销"/></p>
</form>
</body>
</html>

delete.html

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
delete
</body>
</html>

select.html

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
select
</body>
</html>

403.html

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
403
</body>
</html>

创建一个ShiroConfig,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.dalaoyang.config;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @author dalaoyang
 * @Description
 * @project springboot_learn
 * @package com.dalaoyang.config
 * @email yangyang@dalaoyang.cn
 * @date 2018/5/2
 */
@Configuration
public class ShiroConfig {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        logger.info("启动shiroFilter--时间是:" + new Date());
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //shiro拦截器
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
        //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
        //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->

        // 配置不被拦截的资源及链接
        filterChainDefinitionMap.put("/static/**", "anon");
        // 退出过滤器
        filterChainDefinitionMap.put("/logout", "logout");

        //配置需要认证权限的
        filterChainDefinitionMap.put("/**", "authc");
        // 如果不设置默认会自动寻找Web工程根目录下的"/login"页面,即本文使用的login.html
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/index");

        //未授权界面
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    //自定义身份认证Realm(包含用户名密码校验,权限校验等)
    @Bean
    public MyShiroRealm myShiroRealm(){
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        return myShiroRealm;
    }


    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

    //开启shiro aop注解支持,不开启的话权限验证就会失效
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    //配置异常处理,不配置的话没有权限后台报错,前台不会跳转到403页面
    @Bean(name="simpleMappingExceptionResolver")
    public SimpleMappingExceptionResolver
    createSimpleMappingExceptionResolver() {
        SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();
        Properties mappings = new Properties();
        mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理
        mappings.setProperty("UnauthorizedException","403");
        simpleMappingExceptionResolver.setExceptionMappings(mappings);  // None by default
        simpleMappingExceptionResolver.setDefaultErrorView("error");    // No default
        simpleMappingExceptionResolver.setExceptionAttribute("ex");     // Default is "exception"
        return simpleMappingExceptionResolver;
    }
}

在配置一个MyShiroRealm用于登录认证和授权认证,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.dalaoyang.config;

import com.dalaoyang.entity.SysMenu;
import com.dalaoyang.entity.SysRole;
import com.dalaoyang.entity.SysUser;
import com.dalaoyang.repository.UserRepository;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import javax.annotation.Resource;

/**
 * @author dalaoyang
 * @Description
 * @project springboot_learn
 * @package com.dalaoyang.config
 * @email yangyang@dalaoyang.cn
 * @date 2018/5/2
 */
public class MyShiroRealm extends AuthorizingRealm {

    @Resource
    private UserRepository userRepository;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        SysUser userInfo  = (SysUser)principals.getPrimaryPrincipal();
        for(SysRole role:userInfo.getRoleList()){
            authorizationInfo.addRole(role.getRoleName());
            for(SysMenu menu:role.getMenuList()){
                authorizationInfo.addStringPermission(menu.getMenuName());
            }
        }
        return authorizationInfo;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
            throws AuthenticationException {
        //获得当前用户的用户名
        String username = (String)token.getPrincipal();
        System.out.println(token.getCredentials());
        //根据用户名找到对象
        //实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法
        SysUser userInfo = userRepository.findByUserName(username);
        if(userInfo == null){
            return null;
        }
        //这里会去校验密码是否正确
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                userInfo, //用户名
                userInfo.getPassWord(),//密码
                getName()
        );
        return authenticationInfo;
    }
}

最后新建一个controller,其中本文使用了2种验证权限的方法,select方法使用@RequiresPermissions(“select”)来验证用户是否具有select权限,delete方法使用@RequiresRoles(“admin”)来验证用户是否是admin,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.dalaoyang.controller;

import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * @author dalaoyang
 * @Description
 * @project springboot_learn
 * @package com.dalaoyang.controller
 * @email yangyang@dalaoyang.cn
 * @date 2018/5/2
 */
@Controller
public class TestController {

    @GetMapping({"/","/index"})
    public String index(){
        return"index";
    }

    @GetMapping("/403")
    public String unauthorizedRole(){
        return "403";
    }

    @GetMapping("/delete")
    //@RequiresPermissions("delete")
    @RequiresRoles("admin")
    public String delete(){
        return "delete";
    }

    @GetMapping("/select")
    @RequiresPermissions("select")
    public String select(){
        return "select";
    }

    @RequestMapping("/login")
    public String login(HttpServletRequest request, Map<String, Object> map) throws Exception{
        System.out.println("HomeController.login()");
        // 登录失败从request中获取shiro处理的异常信息。
        // shiroLoginFailure:就是shiro异常类的全类名.
        String exception = (String) request.getAttribute("shiroLoginFailure");
        String msg = "";
        //根据异常判断错误类型
        if (exception != null) {
            if (UnknownAccountException.class.getName().equals(exception)) {
                msg = "账号不存在";
            } else if (IncorrectCredentialsException.class.getName().equals(exception)) {
                msg = "密码不正确";
            } else {
                msg = "else >> "+exception;
            }
        }
        map.put("msg", msg);
        // 此方法不处理登录成功,由shiro进行处理
        return "/login";
    }

    @GetMapping("/logout")
    public String logout(){
        return "/login";
    }
}

为了方便测试,本人插入了几条初始数据,sql如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
INSERT INTO `shiro`.`sys_menu`(`menu_id`, `menu_name`) VALUES (1, 'add');
INSERT INTO `shiro`.`sys_menu`(`menu_id`, `menu_name`) VALUES (2, 'delete');
INSERT INTO `shiro`.`sys_menu`(`menu_id`, `menu_name`) VALUES (3, 'update');
INSERT INTO `shiro`.`sys_menu`(`menu_id`, `menu_name`) VALUES (4, 'select');
INSERT INTO `shiro`.`sys_role`(`role_id`, `role_name`) VALUES (1, 'admin');
INSERT INTO `shiro`.`sys_role`(`role_id`, `role_name`) VALUES (2, 'user');
INSERT INTO `shiro`.`sys_role_menu`(`role_id`, `menu_id`) VALUES (1, 1);
INSERT INTO `shiro`.`sys_role_menu`(`role_id`, `menu_id`) VALUES (1, 2);
INSERT INTO `shiro`.`sys_role_menu`(`role_id`, `menu_id`) VALUES (1, 3);
INSERT INTO `shiro`.`sys_role_menu`(`role_id`, `menu_id`) VALUES (1, 4);
INSERT INTO `shiro`.`sys_role_menu`(`role_id`, `menu_id`) VALUES (2, 4);
INSERT INTO `shiro`.`sys_user`(`user_id`, `pass_word`, `user_name`) VALUES (1, '123', 'dalaoyang');
INSERT INTO `shiro`.`sys_user`(`user_id`, `pass_word`, `user_name`) VALUES (2, '123', 'xiaoli');
INSERT INTO `shiro`.`sys_user_role`(`role_id`, `user_id`) VALUES (1, 1);
INSERT INTO `shiro`.`sys_user_role`(`role_id`, `user_id`) VALUES (2, 2);

启动项目,我在这里就不一一截图了,口述一下,访问http://localhost:8888/select由于没有登录的原因,会自动跳转到http://localhost:8888/login,输入错误的用户名和密码会出现对应的提示。输入角色user的用户名xiaoli,密码123。访问http://localhost:8888/select页面会正常跳转,访问http://localhost:8888/delete会拦截到403页面。

如果使用角色为admin的用户dalaoyang密码123登录,以上请求全可以正常访问。

源码下载 :大老杨码云

个人网站:https://dalaoyang.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-05-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python数据分析之Seaborn(配色方案)
配色是图表设计里最重要的方面之一,因为如果配色方案好,它可以清晰展现数据的模式和规律,否则就会把这些规律和模式隐藏起来。 Seaborn让选择和使用配色方案变得简单且适用于你工作的数据种类和你想要达到的可视化目标。
AI异构
2020/07/29
12.5K0
Python数据分析之Seaborn(配色方案)
数据可视化(16)-Seaborn系列 | 变量关系组图pairplot()
案例代码已上传:Github https://github.com/Vambooo/SeabornCN
数据分析可视化
2019/10/02
2.8K0
数据可视化(16)-Seaborn系列 | 变量关系组图pairplot()
seaborn可视化入门
【小提琴图】其实是【箱线图】与【核密度图】的结合,【箱线图】展示了分位数的位置,【小提琴图】则展示了任意位置的密度,通过【小提琴图】可以知道哪些位置的密度较高。 小提琴图的内部是箱线图(有的图中位数会用白点表示,但归根结底都是箱线图的变化);外部包裹的就是核密度图,某区域图形面积越大,某个值附近分布的概率越大。 通过箱线图,可以查看有关数据的基本分布信息,例如中位数,平均值,四分位数,以及最大值和最小值,但不会显示数据在整个范围内的分布。如果数据的分布有多个峰值(也就是数据分布极其不均匀),那么箱线图就无法展现这一信息,这时候小提琴图的优势就展现出来了!
IT从业者张某某
2022/11/12
1.1K0
seaborn可视化入门
python数据科学系列:seaborn入门详细教程
前期,分别对python数据分析三剑客进行了逐一详细入门介绍,今天推出系列第4篇教程:seaborn。这是一个基于matplotlib进行高级封装的可视化库,相比之下,绘制图表更为集成化、绘图风格具有更高的定制性。
luanhz
2020/06/28
16.7K0
python数据科学系列:seaborn入门详细教程
机器学习绘图Seaborn学习
Seaborn是基于Matplotlib的一个高级数据可视化库。它的语法比较简单,用起来很方便。Seaborn可以用来生成多种图形,例如散点图、箱线图、热力图等。它也内置了一些数据集,可以用于测试和练习。
用户6841540
2025/03/17
1920
seaborn数据总体分布的可视化策略
在查看一个数据的分布时,常用的可视化形式有直方图,密度分布图等,在seaborn中,相关的函数有以下几个
生信修炼手册
2020/10/19
1.4K0
Seaborn 基本语法及特点
Seaborn 是 Python 中一个非常受用户欢迎的可视化库。Seaborn 在 Matplotlib 的基础上进行了更加高级的封装,用户能够使用极少的代码绘制出拥有丰富统计信息的科研论文配图。Seaborn 基于 Matplotlib,Matplotlib 中大多数绘图函数的参数都可在 Seaborn 绘图函数中使用,对 Python 的其他库(比如 Numpy/Pandas/Scipy)有很好的支持。
timerring
2023/10/13
4860
Seaborn 基本语法及特点
数据可视化(5)-Seaborn系列 | 柱状图countplot()
案例代码已上传:Github https://github.com/Vambooo/SeabornCN
数据分析可视化
2019/09/23
14.8K0
数据可视化(5)-Seaborn系列 |  柱状图countplot()
seaborn从入门到精通03-绘图功能实现03-分布绘图distributional plots
本文主要是seaborn从入门到精通系列第3篇,本文介绍了seaborn的绘图功能实现,本文是分布绘图,同时介绍了较好的参考文档置于博客前面,读者可以重点查看参考链接。本系列的目的是可以完整的完成seaborn从入门到精通。重点参考连接
IT从业者张某某
2023/10/16
4710
seaborn从入门到精通03-绘图功能实现03-分布绘图distributional plots
数据可视化(13)-Seaborn系列 | 点图pointplot()
注:点图只显示平均值(或其他估计值)。但在许多情况下,显示每个分类变量级别的值分布可能更具信息性。此时,其他方法如一个盒子或小提琴可能更合适。
数据分析可视化
2019/10/02
2.9K0
数据可视化(13)-Seaborn系列 | 点图pointplot()
用Seaborn实现高级数据分析与可视化
今日推荐:零基础入门Hadoop:IntelliJ IDEA远程连接服务器中Hadoop运行WordCount
一键难忘
2024/11/18
4080
seaborn从入门到精通03-绘图功能实现05-构建结构化的网格绘图
本文主要是seaborn从入门到精通系列第3篇,本文介绍了seaborn的绘图功能实现,本文是FacetGrid和PairGrid部分,同时介绍了较好的参考文档置于博客前面,读者可以重点查看参考链接。本系列的目的是可以完整的完成seaborn从入门到精通。重点参考连接
IT从业者张某某
2023/10/16
3620
seaborn从入门到精通03-绘图功能实现05-构建结构化的网格绘图
小白也能看懂的seaborn入门示例
Seaborn就是让困难的东西更加简单。它是针对统计绘图的,一般来说,能满足数据分析90%的绘图需求。Seaborn其实是在matplotlib的基础上进行了更高级的API封装,从而使得作图更加容易,在大多数情况下使用seaborn就能做出很具有吸引力的图,应该把Seaborn视为matplotlib的补充,而不是替代物。
1480
2019/11/07
4.9K0
小白也能看懂的seaborn入门示例
Seaborn从零开始学习教程(二)
在Seaborn的使用中,是可以针对数据类型而选择合适的颜色,并且使用选择的颜色进行可视化,节省了大量的可视化的颜色调整工作。
Python数据科学
2018/08/06
1.6K0
Seaborn从零开始学习教程(二)
数据可视化(11)-Seaborn系列 | 小提琴图violinplot()
小提琴形图(violin plot)的作用与盒形图(box plot)和whidker plot的作用类似,它显示了一个或多个分类变量的几个级别的定量数据的分布,我们可以通过观察来比较这些分布。与盒形图不同,因为盒形图的所有绘图组件都对应于实际数据点,小提琴形图具有底层分布的核密度估计。
数据分析可视化
2019/10/02
13.8K0
数据可视化(11)-Seaborn系列 | 小提琴图violinplot()
可视化神器Seaborn的超全介绍
Seaborn是一个用Python制作统计图形的库。它建立在matplotlib之上,并与panda数据结构紧密集成
HuangWeiAI
2019/12/30
2.4K0
seaborn可视化绘图
今天给大家介绍基于seaborn的4份内置数据集绘制24个精美图形,代码复制即可运行。
皮大大
2024/06/14
2960
Python 可视化实战:用 Matplotlib + Seaborn 打造专业级图表仪表盘
本篇文章重点讲解:Matplotlib + Seaborn,通过基础到实战构建出一个完整的数据分析图表仪表盘。
用户11690571
2025/06/10
2900
70个精美图快速上手seaborn!
Seaborn是一个基于Python的数据可视化库,它建立在Matplotlib之上,提供了一种更简单、更美观的方式来创建统计图形。Seaborn旨在帮助用户轻松地生成有吸引力和信息丰富的可视化结果。
皮大大
2023/05/31
2.8K0
70个精美图快速上手seaborn!
Seaborn 可视化
Seaborn是基于matplotlib的图形可视化python包。它提供了一种高度交互式界面,便于用户能够做出各种有吸引力的统计图表。
@小森
2024/03/15
3850
Seaborn 可视化
推荐阅读
相关推荐
Python数据分析之Seaborn(配色方案)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档